You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
19042 lines
547 KiB
19042 lines
547 KiB
#!/bin/sh
|
|
# the next line restarts using wish \
|
|
exec wish "$0" "$@"
|
|
|
|
#
|
|
# Copyright (c) 2006-2010 by Karl J. Runge <runge@karlrunge.com>
|
|
#
|
|
# ssvnc.tcl: gui wrapper to the programs in this
|
|
# package. Also sets up service port forwarding.
|
|
#
|
|
set version 1.0.28
|
|
|
|
set buck_zero $argv0
|
|
|
|
proc center_win {w} {
|
|
global is_windows
|
|
update
|
|
set W [winfo screenwidth $w]
|
|
set W [expr $W + 1]
|
|
wm geometry $w +$W+0
|
|
update
|
|
set x [expr [winfo screenwidth $w]/2 - [winfo width $w]/2]
|
|
set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2]
|
|
|
|
if {$is_windows} {
|
|
set y [expr "$y - 30"]
|
|
if {$y <= 0} {
|
|
set y 1
|
|
}
|
|
}
|
|
wm geometry $w +$x+$y
|
|
wm deiconify $w
|
|
update
|
|
}
|
|
|
|
proc small_height {} {
|
|
set H [winfo screenheight .]
|
|
if {$H < 700} {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
proc mac_raise {} {
|
|
global uname
|
|
if {$uname == "Darwin"} {
|
|
catch {exec /bin/sh -c {osascript -e 'tell application "Wish Shell" to activate' >/dev/null 2>&1 &}}
|
|
after 150
|
|
update
|
|
update idletasks
|
|
}
|
|
}
|
|
|
|
proc toplev {w} {
|
|
catch {destroy $w}
|
|
toplevel $w
|
|
catch {wm withdraw $w}
|
|
}
|
|
|
|
proc apply_bg {w} {
|
|
global is_windows system_button_face
|
|
if {$is_windows && $system_button_face != ""} {
|
|
catch {$w configure -bg "$system_button_face"}
|
|
}
|
|
}
|
|
|
|
proc line_count {{str ""} {pad 0}} {
|
|
set n $pad
|
|
foreach l [split $str "\n"] {
|
|
incr n
|
|
}
|
|
return $n
|
|
}
|
|
|
|
proc scroll_text {fr {w 80} {h 35}} {
|
|
global help_font is_windows scroll_text_focus
|
|
|
|
if {$h == 35 && [small_height]} {
|
|
set h 28
|
|
}
|
|
catch {destroy $fr}
|
|
|
|
frame $fr -bd 0
|
|
|
|
eval text $fr.t -width $w -height $h $help_font \
|
|
-setgrid 1 -bd 2 -yscrollcommand {"$fr.y set"} -relief ridge
|
|
|
|
apply_bg $fr.t
|
|
|
|
scrollbar $fr.y -orient v -relief sunken -command "$fr.t yview"
|
|
pack $fr.y -side right -fill y
|
|
pack $fr.t -side top -fill both -expand 1
|
|
|
|
if {$scroll_text_focus} {
|
|
focus $fr.t
|
|
}
|
|
}
|
|
|
|
proc scroll_text_dismiss {fr {w 80} {h 35}} {
|
|
global help_font
|
|
|
|
if {$h == 35 && [small_height]} {
|
|
set h 28
|
|
}
|
|
scroll_text $fr $w $h
|
|
|
|
set up $fr
|
|
regsub {\.[^.]*$} $up "" up
|
|
|
|
button $up.d -text "Dismiss" -command "destroy $up"
|
|
bind $up <Escape> "destroy $up"
|
|
pack $up.d -side bottom -fill x
|
|
pack $fr -side top -fill both -expand 1
|
|
}
|
|
|
|
proc jiggle_text {w} {
|
|
global uname
|
|
if {$uname == "Darwin"} {
|
|
$w yview scroll 1 pages
|
|
update idletasks
|
|
$w yview scroll -1 pages
|
|
update idletasks
|
|
}
|
|
}
|
|
|
|
proc ts_help {} {
|
|
toplev .h
|
|
|
|
scroll_text_dismiss .h.f
|
|
|
|
center_win .h
|
|
wm title .h "Terminal Services VNC Viewer Help"
|
|
|
|
set msg {
|
|
Terminal Services:
|
|
|
|
The Terminal Services VNC Viewer uses SSH to establish an encrypted
|
|
and authenticated connection to the remote server.
|
|
|
|
Through the SSH channel, it automatically starts x11vnc in terminal
|
|
services mode on the remote server to find or create your desktop
|
|
session. x11vnc is used for both the session management and the
|
|
VNC transport.
|
|
|
|
You MUST be able to log in via SSH to the remote terminal server.
|
|
Ask your administrator to set this up for you if it isn't already.
|
|
x11vnc must also be installed on the remote server machine.
|
|
See "Requirements" below.
|
|
|
|
This mode is started by the commands 'tsvnc' or 'ssvnc -ts' or
|
|
toggled by pressing Ctrl-t. "SSVNC Mode" under Options -> Advanced
|
|
will also return to the full SSVNC.
|
|
|
|
Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
|
|
to have the tool always start up in that mode. To constrain the UI,
|
|
run with -tso or SSVNC_TS_ALWAYS set to prevent leaving the Terminal
|
|
Services mode.
|
|
|
|
|
|
Hosts and Displays:
|
|
|
|
Enter the remote VNC Terminal Services hostname in the
|
|
'VNC Terminal Server' entry.
|
|
|
|
Examples:
|
|
|
|
24.67.132.27
|
|
far-away.east
|
|
fred@someplace.no
|
|
|
|
Then click on "Connect".
|
|
|
|
Once the SSH is running (you may need to type a password or accept
|
|
a new ssh key in the terminal window that pops up), the VNC Viewer
|
|
will be automatically started directed to the local port of the SSH
|
|
tunnel which, in turn, encrypts and redirects the connection to the
|
|
remote VNC server.
|
|
|
|
x11vnc is run remotely to find or create your terminal services desktop
|
|
session. It must be installed and accessible on the remote system.
|
|
|
|
Enter "user@hostname.com" in 'VNC Terminal Server' if the remote
|
|
username is different from the yours on this machine. On Windows
|
|
you *MUST* supply the remote username due to a deficiency in Plink.
|
|
This entry is passed to SSH; it could also be an SSH alias you have
|
|
created (in ~/.ssh/config).
|
|
|
|
If the remote SSH server is run on a non-standard port, e.g. 2222, use
|
|
something like one of these:
|
|
|
|
far-away.east:2222
|
|
fred@someplace.no:2222
|
|
|
|
(unlike SSVNC mode, the number is the SSH port, not the VNC display)
|
|
|
|
If you find yourself in the unfortunate circumstance that your ssh
|
|
username has a space in it, use %SPACE (or %TAB) like this:
|
|
|
|
fred%SPACEflintstone@xyzzy.net
|
|
|
|
|
|
Zeroconf/Bonjour:
|
|
|
|
On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is
|
|
available on the system and in your PATH, a 'Find' button is placed by
|
|
'VNC Host:Display'. Clicking on Find will try to find VNC Servers
|
|
on your Local Network that advertize via the Zeroconf protocol.
|
|
A menu of found hosts is presented for you to select from.
|
|
|
|
|
|
Profiles:
|
|
|
|
Use "Save" to save a profile (i.e. a host:display and its specific
|
|
settings) with a name. The "TS-" prefix will be suggested to help
|
|
you distinguish between Terminal Services and regular profiles.
|
|
|
|
To load in a saved Options profile, click on the "Load" button,
|
|
and choose which one you want.
|
|
|
|
To list your profiles from the command line use:
|
|
|
|
tsvnc -profiles (or -list)
|
|
|
|
To launch profile1 directly from the command-line, or to a server
|
|
use things like:
|
|
|
|
tsvnc profile1
|
|
tsvnc /path/to/profile1.vnc
|
|
tsvnc hostname
|
|
tsvnc user@hostname
|
|
|
|
Note that the 'Verify All Certs' setting is NOT saved in profiles.
|
|
|
|
|
|
Proxies/Gateways:
|
|
|
|
Proxy/Gateway is usually a gateway machine to log into via SSH that is
|
|
not the machine running the VNC terminal services. However, Web and
|
|
SOCKS proxies can also be used (see below).
|
|
|
|
For example if a company had a central login server: "ssh.company.com"
|
|
(accessible from the internet) and the internal server name was
|
|
"ts-server", one could put in
|
|
|
|
VNC Terminal Server: ts-server
|
|
Proxy/Gateway: ssh.company.com
|
|
|
|
It is OK if the hostname "ts-server" only resolves inside the firewall.
|
|
|
|
The 2nd host, ts-server in this example, MUST also be running an SSH
|
|
server and you must be able to log into it. You may need to supply
|
|
a 2nd password to it to login.
|
|
|
|
Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com)
|
|
if the user name differs between machines.
|
|
|
|
NOTE: On Windows you MUST always supply the username@ because putty's
|
|
plink requires it.
|
|
|
|
|
|
NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
|
|
than 22) you need to use the Proxy/Gateways as well. E.g. something
|
|
like this for port 2222:
|
|
|
|
VNC Terminal Server: ts-server
|
|
Proxy/Gateway: jsmith@ssh.company.com:2222
|
|
|
|
On Unix/MacOSX the username@ is not needed if it is the same as on this
|
|
machine.
|
|
|
|
|
|
A Web or SOCKS proxy can also be used. Use this if you are inside a
|
|
firewall that prohibits direct connections to remote SSH servers.
|
|
In Terminal Services SSH mode, the "http://" prefix is required for
|
|
web proxies.
|
|
|
|
VNC Terminal Server: fred@someplace.no
|
|
Proxy/Gateway: http://myproxy.west:8080
|
|
|
|
or for SOCKS:
|
|
|
|
VNC Terminal Server: fred@someplace.no
|
|
Proxy/Gateway: socks://mysocks.west:1080
|
|
|
|
use socks5://... to force the SOCKS5 version. For a non-standard
|
|
port the above would be, e.g., fred@someplace.no:2222
|
|
|
|
As with a username that contains a space, use %SPACE (or %TAB) to
|
|
indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com
|
|
|
|
One can also chain proxies and other things. See the section
|
|
"SSH Proxies/Gateways" in the Main SSVNC Help for full details.
|
|
|
|
|
|
Options:
|
|
|
|
Click on Options to get to dialog boxes to:
|
|
|
|
- Desktop Type (kde, gnome, failsafe, twm...)
|
|
- Desktop Size (Geometry WxH and pixel depth)
|
|
- X Server Type (Xvfb, Xdummy, Xvnc)
|
|
- Enable Printing (CUPS and/or SMB/Windows)
|
|
- Enable Sound (TBD, ESD partially working)
|
|
- File Transfer (Ultra or TightVNC filexfer)
|
|
- View Only (View only client)
|
|
- Change VNC Viewer (Realvnc, ultra, etc...)
|
|
- X11 viewer MacOSX (use bundled X11 vncviewer)
|
|
- Delete Profile... (Delete a saved profile)
|
|
|
|
- Advanced Options:
|
|
|
|
- VNC Shared (optional traditional VNC sharing)
|
|
- Multiple Sessions (more than 1 session per server)
|
|
- X Login Greeter (Connect to Login/Greeter Display)
|
|
- Other VNC Server (redirect to 3rd party VNC Server)
|
|
- Use unixpw (optional x11vnc login mode)
|
|
- Client 8bit Color (VNC Viewer requests low color mode)
|
|
- Client-Side Caching (experimental x11vnc speedup)
|
|
- X11VNC Options (set any extra x11vnc options)
|
|
- Extra Sleep (delay a bit before starting viewer)
|
|
- Putty Args (Windows: string for plink/putty cmd)
|
|
- Putty Agent (Windows: launch pageant)
|
|
- Putty Key-Gen (Windows: launch puttygen)
|
|
- SSH Local Protections (a bit of safety on local side)
|
|
- SSH KnownHosts file (to avoid SSH 'localhost' collisions)
|
|
- SSVNC Mode (Return to full SSVNC mode)
|
|
|
|
- Unix ssvncviewer (set options for supplied Unix viewer)
|
|
|
|
|
|
Requirements:
|
|
|
|
When running this application on Unix/MacOSX the ssh(1) program must
|
|
be installed locally. On Windows a plink/putty binary is included.
|
|
|
|
On the remote VNC Terminal Services host, x11vnc must be installed
|
|
(0.9.3 or higher), and at least one virtual X server: Xvfb, Xdummy,
|
|
or Xvnc must be available. Xvfb is the most often used one. All of
|
|
these programs must be available in $PATH on the remote server when
|
|
logged in via SSH.
|
|
|
|
The VNC terminal services administrator can make "x11vnc" be a wrapper
|
|
script that sets everything up correctly and then runs the real x11vnc.
|
|
|
|
|
|
Real X servers:
|
|
|
|
As a *BONUS*, if on the remote host, say a workstation, you have a
|
|
regular X session running on the physical hardware that you are
|
|
ALREADY logged into you can access to that display as well (x11vnc
|
|
will find it).
|
|
|
|
So this tool can be used as a simple way to launch x11vnc to find
|
|
your real X display on your workstation and connect to it.
|
|
|
|
The Printing and Sound redirection won't work for this mode however.
|
|
You will need to use the full SSVNC application to attempt that.
|
|
|
|
If you (mistakenly) have not logged into an X session on the real
|
|
X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be
|
|
created for you (that may or may not be what you want).
|
|
|
|
The X Login Advanced setting can be used to connect to a X Display
|
|
Manger Greeter login panel (no one is logged in yet). This requires
|
|
sudo(1) privileges on the remote machine.
|
|
|
|
More Info:
|
|
|
|
See these links for more information:
|
|
|
|
http://www.karlrunge.com/x11vnc/#tunnelling
|
|
}
|
|
|
|
global version
|
|
set msg " SSVNC version: $version\n$msg"
|
|
|
|
.h.f.t insert end $msg
|
|
jiggle_text .h.f.t
|
|
}
|
|
|
|
proc help {} {
|
|
global ts_only
|
|
if {$ts_only} {
|
|
ts_help
|
|
return
|
|
}
|
|
toplev .h
|
|
|
|
set h 37
|
|
if [small_height] {
|
|
set h 26
|
|
}
|
|
scroll_text_dismiss .h.f 82 $h
|
|
|
|
center_win .h
|
|
wm title .h "SSL/SSH VNC Viewer Help"
|
|
|
|
global help_main help_prox help_misc help_tips
|
|
|
|
set help_main {
|
|
Hosts and Displays:
|
|
|
|
Enter the VNC host and display in the 'VNC Host:Display' entry box.
|
|
|
|
It is of the form "host:number", where "host" is the hostname of the
|
|
machine running the VNC Server and "number" is the VNC display number;
|
|
it is often "0". Some Examples:
|
|
|
|
snoopy:0
|
|
|
|
far-away.east:0
|
|
|
|
sunray-srv1.west:17
|
|
|
|
24.67.132.27:0
|
|
|
|
Then click on "Connect". When you do the STUNNEL program will be started
|
|
locally to provide you with an outgoing SSL tunnel.
|
|
|
|
Once the STUNNEL is running, the TightVNC Viewer (Or perhaps Chicken of
|
|
the VNC on Mac OS X, or one you set under Options) will be automatically
|
|
started and directed to the local port of the SSL tunnel which, in turn,
|
|
encrypts and redirects the connection to the remote VNC server.
|
|
|
|
The remote VNC server **MUST** support an initial SSL/TLS handshake before
|
|
using the VNC protocol (i.e. VNC is tunnelled through the SSL channel
|
|
after it is established). "x11vnc -ssl ..." does this, and any VNC server
|
|
can be made to do this by using, e.g., STUNNEL or socat on the remote side.
|
|
SSVNC also supports VeNCrypt and ANONTLS SSL/TLS VNC servers (see below.)
|
|
|
|
* Automatic SSH Tunnels are described below.
|
|
|
|
* The 'No Encryption' / 'None' option provides a direct connection without
|
|
encryption (disable the button with the -enc option, or Options menu.)
|
|
More info in Tip 5.
|
|
|
|
Port numbers:
|
|
|
|
If you are using a port less than the default VNC port 5900 (usually
|
|
the VNC display = port - 5900), use the full port number itself, e.g.:
|
|
|
|
24.67.132.27:443
|
|
|
|
Note, however, if the number n after the colon is < 200, then a
|
|
port number 5900 + n is assumed; i.e. n is the VNC display number.
|
|
If you must use a TCP port less than 200, specify a negative value,
|
|
e.g.: 24.67.132.27:-80
|
|
|
|
For Reverse VNC connections (listening viewer, See Tip 2 and
|
|
Options -> Help), the port mapping is similar, except "listening
|
|
display :0" corresponds to port 5500, :1 to 5501, etc.
|
|
Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
|
|
listen on that interface only. Listening on IPv6 can also be done, use
|
|
e.g. :::0 or ::1:0 This listening on IPv6 (:::0) works for UN-encrypted
|
|
reverse connections as well (mode 'None').
|
|
|
|
|
|
Zeroconf/Bonjour:
|
|
|
|
On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is
|
|
available on the system and in your PATH, a 'Find' button is placed by
|
|
'VNC Host:Display'. Clicking on Find will try to find VNC Servers on
|
|
your Local Network that advertize via the Zeroconf protocol. A menu of
|
|
found hosts is presented for you to select from.
|
|
|
|
|
|
VNC Password:
|
|
|
|
On Unix or MacOSX IF there is a VNC password for the server you can
|
|
enter it in the "VNC Password:" entry box.
|
|
|
|
This is *REQUIRED* on MacOSX when Chicken of the VNC is used, because
|
|
that viewer does not put up a user password prompt when it learns
|
|
that a password is needed.
|
|
|
|
On Unix (including MacOSX using the X11 viewer) if you choose not to
|
|
enter the password you will simply be prompted for it in the terminal
|
|
window running TightVNC viewer if one is required.
|
|
|
|
On Windows TightVNC viewer will prompt you if a password is required.
|
|
|
|
NOTE: when you Save a VNC profile, the password is NOT saved (you need
|
|
to enter it each time). Nor is the 'Verify All Certs' setting.
|
|
|
|
|
|
Profiles:
|
|
|
|
Use "Save" to save a profile (i.e. a host:display and its specific
|
|
settings) with a name.
|
|
|
|
To load in a saved Options profile, click on the "Load" button.
|
|
|
|
To list your profiles from the command line use:
|
|
|
|
ssvnc -profiles (or -list)
|
|
|
|
You can launch ssvnc and have it immediately connect to the server
|
|
by invoking it something like this:
|
|
|
|
ssvnc profile1 (launches profile named "profile1")
|
|
ssvnc /path/to/profile.vnc (loads the profile file, no launching)
|
|
ssvnc hostname:0 (connect to hostname VNC disp 0 via SSL)
|
|
ssvnc vnc+ssl://hostname:0 (same)
|
|
ssvnc vnc+ssh://hostname:0 (connect to hostname VNC disp 0 via SSH)
|
|
|
|
see the Tips 5 and 7 for more about the URL-like syntax.
|
|
|
|
If you don't want "ssvnc profile1" to immediately launch the connection
|
|
to the VNC server set the SSVNC_PROFILE_LOADONLY env. var. to 1.
|
|
(or specify the full path to the profile.vnc as shown above.)
|
|
|
|
|
|
SSL Certificate Verification:
|
|
|
|
*** IMPORTANT ***: If you do not take the steps to VERIFY the VNC Server's
|
|
SSL Certificate, you are in principle vulnerable to a Man-In-The-Middle
|
|
attack. Without SSL Certificate verification, only passive network
|
|
sniffing attacks will be guaranteed to be prevented. There are hacker
|
|
tools like dsniff/webmitm and cain that implement SSL Man-In-The-Middle
|
|
attacks. They rely on the client user not bothering to check the cert.
|
|
|
|
Some people may be confused by the above because they are familiar with
|
|
their Web Browser using SSL (i.e. https://... websites) and those sites
|
|
are authenticated securely without the user's need to verify anything
|
|
manually. The reason why this happens automatically is because 1) their
|
|
web browser comes with a bundle of Certificate Authority certificates
|
|
and 2) the https sites have paid money to the Certificate Authorities to
|
|
have their website certificate signed by them. When using SSL in VNC we
|
|
normally do not do something this sophisticated, and so we have to verify
|
|
the certificates manually. However, it is possible to use Certificate
|
|
Authorities with SSVNC; that method is described below.
|
|
|
|
You can use the "Fetch Cert" button to retrieve the Cert and then
|
|
after you check it is OK (say, via comparing the MD5 or other info)
|
|
you can "Save" it and use it to verify future connections to servers.
|
|
(However, see the note at the end of this section about CA certificates.)
|
|
|
|
When "Verify All Certs" is checked, this check is always enforced,
|
|
and so the first time you connect to a new server you may need to
|
|
follow a few dialogs to inspect and save the server certificate.
|
|
See the "Certs... -> Help" for information on how to manage certificates.
|
|
|
|
"Verify All Certs" is on by default.
|
|
|
|
Note, however, "Fetch Cert" and "Verify All Certs" are currently disabled
|
|
in the very rare "SSH + SSL" usage mode to avoid SSHing in twice.
|
|
You can manually set a ServerCert or CertsDir in this case if you like.
|
|
|
|
|
|
Advanced Method: Certificate Authority (CA):
|
|
|
|
If you, or your site administrator, goes though the steps of setting up
|
|
a Certificate Authority (CA) to sign the VNC server and/or VNC client
|
|
Certs, that can be used instead and avoids the need to manually verify
|
|
every cert while still authenticating every connection. More info:
|
|
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
|
|
|
|
See the cmdline option -cacert file below in 'SSL Certificates'
|
|
for setting a default ServerCert/CA Cert.
|
|
|
|
You may also Import the CA Cert and save it to the 'Accepted Certs'
|
|
directory so the "Verify All Certs" automatic checking will find it.
|
|
|
|
Note that if a Server is using a CA signed certificate instead of
|
|
its own Self-Signed one, then the default "Verify All Certs/Fetch Cert"
|
|
saving mechanism will NOT succeed. You must obtain the CA certificate
|
|
and explicitly set it as the ServerCert or Import it to Accepted Certs.
|
|
|
|
|
|
SSL/TLS Variants; VeNCrypt and ANONTLS:
|
|
|
|
SSVNC can also connect to VNC SSL/TLS variants; namely the VeNCrypt and
|
|
"TLS" VNC Security types. Vino uses the latter (we call it "ANONTLS");
|
|
and a growing number use VeNCrypt (QEMU, ggi, virt-manager, VeNCrypt, Xen.)
|
|
|
|
Via the VeNCrypt bridge that SSVNC provides, the VeNCrypt/ANONTLS
|
|
support ALSO works with ANY 3rd party VNC Viewers you specify via
|
|
'Change VNC Viewer' (e.g. RealVNC, TightVNC, UltraVNC, etc.) that do
|
|
not directly support VeNCrypt or ANONTLS. This works on all platforms:
|
|
Unix, MacOSX, and Windows.
|
|
|
|
|
|
Notes on VeNCrypt/ANONTLS Auto-detection:
|
|
|
|
IMPORTANT: VeNCrypt Server Auto-detection *ONLY* occurs in SSL mode
|
|
and when an initial fetch-cert action takes place.
|
|
|
|
While the initial certificate fetch is taking place SSVNC applies
|
|
heuristics to try to automatically detect the VeNCrypt or ANONTLS
|
|
protocol use by the VNC server. This way it learns that the server
|
|
is using it and then knows to switch to VeNCrypt encrypted SSL/TLS at
|
|
the right point. Then SSVNC makes a second (the real) connection to
|
|
VNC server and connects the VNC viewer to it.
|
|
|
|
In the default "Verify All Certs" mode, a fetch cert action always
|
|
takes place, and so VeNCrypt/ANONTLS will be autodected.
|
|
|
|
However, if you have specified an explicit ServerCert or disabled
|
|
"Verify All Certs" then even though the initial fetch cert action is no
|
|
longer needed, it is performed anyway because it allows VeNCrypt/ANONTLS
|
|
auto-detection.
|
|
|
|
To disabled this initial fetch (e.g. you know the VNC server is normal
|
|
SSL and not VeNCrypt/ANONTLS and want to connect more quickly) then
|
|
select "Do not Probe for VeNCrypt" in the Advanced Options menu.
|
|
|
|
On the other hand, if you know the VNC server ONLY supports VeNCrypt or
|
|
ANONTLS, to improve the accuracy and speed with which the connection
|
|
takes place, you can specify the one or both of the 'Server uses
|
|
VeNCrypt SSL encryption' and 'Server uses Anonymous Diffie-Hellman'
|
|
in the 'Advanced' options panel. That way guessing via an initial
|
|
probe is not needed or performed. See each options's Advanced Options
|
|
Help for more info.
|
|
|
|
Note that if you are using VeNCrypt or ANONTLS for REVERSE connections
|
|
(Listen) then you *MUST* set the 'Server uses VeNCrypt SSL encryption'
|
|
(and the ANON-DH if it applies) option in Advanced. Note also that
|
|
REVERSE VeNCrypt and ANONTLS connections currently do not work on
|
|
Windows.
|
|
|
|
Also, if you are using the "Use SSH+SSL" double tunnel, you MUST set
|
|
'Server uses VeNCrypt SSL encryption' (and the ANON-DH if it applies)
|
|
because the initial fetch cert is disabled in SSH+SSL mode.
|
|
|
|
|
|
Deciphering SSL Negotiation Success or Failure:
|
|
|
|
Since SSVNC is a "glue program", in this case gluing VNCViewer and stunnel
|
|
together (with possibly a proxy helper) reporting is clumsy at best.
|
|
(In SSH encryption mode, it glues to ssh instead of stunnel.) In most
|
|
cases the programs being "glued" are run in a terminal window where you
|
|
can see the program's output. On Windows you will need to double click
|
|
on the stunnel tray icon to view its log.
|
|
|
|
Although the output is quite cryptic, you are encouraged to learn to
|
|
recognize some of the errors reported in it.
|
|
|
|
Here is stunnel output for a case of successfully verifying the VNC
|
|
Server's Certificate:
|
|
|
|
2008.11.20 08:09:39 LOG5[1472]: VERIFY OK: depth=0, /C=AU/L=...
|
|
2008.11.20 08:09:39 LOG6[1472]: SSL connected: new session negotiated
|
|
2008.11.20 08:09:39 LOG6[1472]: Negotiated ciphers: AES256-SHA SSLv3 ...
|
|
|
|
Here is a case where the Server's Cert did not match the ServerCert
|
|
we set:
|
|
|
|
2008.11.20 08:12:31 LOG4[1662]: VERIFY ERROR: depth=0, error=self ...
|
|
2008.11.20 08:12:31 LOG3[1662]: SSL_connect: 14090086: error:14090086:SSL
|
|
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
|
|
|
|
Here is a case where the Server's Cert has expired:
|
|
|
|
2009.12.27 12:20:25 LOG4[25500]: VERIFY ERROR: depth=0, error=certificate
|
|
has expired: /C=AU/L=...
|
|
2009.12.27 12:20:25 LOG3[25500]: SSL_connect: 14090086: error:14090086:SSL
|
|
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
|
|
|
|
|
|
If you disable "Verify All Certs" and do not supply a ServerCert,
|
|
then there will be no 'VERIFY ...' in the output because the SSVNC
|
|
stunnel accepts the server's cert without question (this is insecure.)
|
|
|
|
Also in the output will be messages about whether the SSL VNC server
|
|
rejected your connection because it requires you to authenticate
|
|
yourself with a certificate (MyCert). Here is the case when you
|
|
supplied no MyCert:
|
|
|
|
2008.11.20 08:16:29 LOG3[1746]: SSL_connect: 14094410: error:14094410:
|
|
SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
|
|
|
|
or you used a certificate the server did not recognize:
|
|
|
|
2008.11.20 08:18:46 LOG3[1782]: SSL_connect: 14094412: error:14094412:
|
|
SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
|
|
|
|
or your certificate has been revoked:
|
|
|
|
2008.11.20 08:20:08 LOG3[1913]: SSL_connect: 14094414: error:14094414:
|
|
SSL routines:SSL3_READ_BYTES:sslv3 alert certificate revoked
|
|
|
|
|
|
SSH:
|
|
|
|
Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL
|
|
(then the VNC Server does not need to speak SSL or use STUNNEL or socat).
|
|
|
|
You will need to be able to login to your account on the remote host
|
|
via SSH (e.g. via password, ssh keys, or ssh-agent).
|
|
|
|
Specify the SSH hostname and VNC display in the VNC Host:Display entry.
|
|
Use something like:
|
|
|
|
username@far-away.east:0
|
|
|
|
if your remote username is different from the one on the local viewer
|
|
machine.
|
|
|
|
On Windows you *MUST* supply the "username@" part because Putty/Plink
|
|
needs it to work correctly.
|
|
|
|
"SSH + SSL" is similar but its use is more rare because it requires 2
|
|
encrypted tunnels to reach the VNC server. See the Help under Options
|
|
for more info.
|
|
|
|
To connect to a non-standard SSH port, see SSH Proxies/Gateways section.
|
|
|
|
See Tip 8) for how to make this application be SSH-only with the -ssh
|
|
command line option or "sshvnc".
|
|
|
|
If you find yourself in the unfortunate circumstance that your ssh
|
|
username has a space in it, use %SPACE (or %TAB) like this:
|
|
|
|
fred%SPACEflintstone@xyzzy.net:0
|
|
|
|
Remote SSH Command:
|
|
|
|
In SSH or SSH + SSL mode you can also specify a remote command to run
|
|
on the remote ssh host in the "Remote SSH Command" entry. The default
|
|
is just to sleep a bit (e.g. sleep 15) to make sure the tunnel ports
|
|
are established. Alternatively you could have the remote command start
|
|
the VNC server, e.g.
|
|
|
|
x11vnc -display :0 -rfbport 5900 -localhost -nopw
|
|
|
|
When starting the VNC server this way, note that sometimes you will need
|
|
to correlate the VNC Display number with the "-rfbport" (or similar)
|
|
option of the server. E.g. for VNC display :2
|
|
|
|
VNC Host:Display username@somehost.com:2
|
|
Remote SSH Command: x11vnc -find -rfbport 5902 -nopw
|
|
|
|
See the Tip 18) for using x11vnc PORT=NNNN feature (or vncserver(1)
|
|
output) to not need to specify the VNC display number or the x11vnc
|
|
-rfbport option.
|
|
|
|
Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN SSHD
|
|
server) there may be no "sleep" command so put in something like
|
|
"ping localhost" or "ping -n 10 -w 1000 localhost" to set a short
|
|
delay to let the tunnel ports get established.
|
|
|
|
|
|
SSL Certificates:
|
|
|
|
If you want to use a SSL Certificate (PEM) file to authenticate YOURSELF to
|
|
the VNC server ("MyCert") and/or to verify the identity of the VNC Server
|
|
("ServerCert" or "CertsDir") select the certificate file by clicking the
|
|
"Certs ..." button before connecting.
|
|
|
|
Certificate verification is needed to prevent Man-In-The-Middle attacks;
|
|
if it is not done then only passive network sniffing attacks are prevented.
|
|
There are hacker tools like dsniff/webmitm and cain that implement SSL
|
|
Man-In-The-Middle attacks. They rely on the client user not bothering to
|
|
check the cert.
|
|
|
|
|
|
See the x11vnc documentation:
|
|
|
|
http://www.karlrunge.com/x11vnc/ssl.html
|
|
|
|
for how to create and use PEM SSL certificate files. An easy way is:
|
|
|
|
x11vnc -ssl SAVE ...
|
|
|
|
where it will print out its automatically generated certificate to the
|
|
screen and that can be copied safely to the viewer side.
|
|
|
|
You can also use the "Create Certificate" feature of this program under
|
|
"Certs ...". Just click on it and follow the instructions in the dialog.
|
|
Then copy the cert file to the VNC Server and specify the other one in
|
|
the "Certs ..." dialog.
|
|
|
|
Alternatively you can use the "Import Certificate" action to paste in a
|
|
certificate or read one in from a file. Or you can use the "Fetch Cert"
|
|
button on the main panel. If "Verify All Certs" is checked, you will
|
|
be forced to check Certs of any new servers the first time you connect.
|
|
|
|
Note that "Verify All Certs" is on by default so that users who do not
|
|
understand the SSL Man-In-The-Middle problem will not be left completely
|
|
vulnerable to it (everyone still must make the effort to verify new
|
|
certificates by an external method to be completely safe).
|
|
|
|
To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or
|
|
set SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to
|
|
see the button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1.
|
|
|
|
Use the "-mycert file" option (same as "-cert file") to set a default
|
|
MyCert. This is the same as "mycert=file" (also "cert=file") in the
|
|
~/.ssvncrc file. See Certs -> Help for more info.
|
|
|
|
Use the "-cacert file" option (same as "-ca file") to set a default
|
|
ServerCert (or CA). This is the same as "cacert=file" (also "ca=file")
|
|
in the ~/.ssvncrc file. See Certs -> Help for more info.
|
|
|
|
Use the "-crl file" option to set a default CRL File. This is the same
|
|
as "crl=file" in the ~/.ssvncrc file. See Certs -> Help for more info.
|
|
|
|
Prefix any of these files with "FORCE:" to make them immutable.
|
|
|
|
|
|
|
|
More Options:
|
|
|
|
To set other Options, e.g. for View-Only usage or to limit the number
|
|
of colors used, click on the "Options ..." button and read the Help there.
|
|
|
|
More Info:
|
|
|
|
Press the 'Proxies', 'Misc', and 'Tips' buttons below.
|
|
|
|
See also these links for more information:
|
|
|
|
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
|
|
http://stunnel.mirt.net
|
|
http://www.tightvnc.com
|
|
}
|
|
|
|
set help_misc {
|
|
Windows STUNNEL problems:
|
|
|
|
Note that on Windows when the Viewer connection is finished by default
|
|
SSVNC will try to kill the STUNNEL process for you.
|
|
|
|
If Options -> Kill Stunnel Automatically is not set you will be
|
|
prompted if you want SSVNC to try to kill the STUNNEL process for you.
|
|
Usually you will say Yes, however if there are problems connecting
|
|
you may want to look at the STUNNEL Log first.
|
|
|
|
Before it is killed, double clicking the STUNNEL tray icon (dark green)
|
|
will show you its Log file (useful for debugging connection problems).
|
|
|
|
Even though SSVNC will kill the STUNNEL process for you, you will
|
|
still need to move the mouse over the icon to make the little picture
|
|
go away!!! This is unfortunate but there does not seem to be a way
|
|
to avoid it.
|
|
|
|
In some cases you may need to terminate STUNNEL manually from the System
|
|
Tray (right click on dark green icon) and selecting "Exit".
|
|
|
|
Use -nokillstunnel or killstunnel=0 in ~/.ssvncrc to have SSVNC
|
|
start up with stunnel killing disabled.
|
|
|
|
Untrusted Local Users:
|
|
|
|
*IMPORTANT WARNING*: If you run SSVNC on a workstation or computer
|
|
that other users can log into and you DO NOT TRUST these users
|
|
(it is a shame but sometimes one has to work in an environment like
|
|
this), then please note the following warning.
|
|
|
|
By 'do not trust' we mean they might try to gain access to remote
|
|
machines you connect to via SSVNC. Note that an untrusted local
|
|
user can often obtain root access in a short amount of time; if a
|
|
user has achieved that, then all bets are off for ANYTHING that you
|
|
do on the workstation. It is best to get rid of Untrusted Local
|
|
Users as soon as possible.
|
|
|
|
Both the SSL and SSH tunnels set up by SSVNC listen on certain ports
|
|
on the 'localhost' address and redirect TCP connections to the remote
|
|
machine; usually the VNC server running there (but it could also be
|
|
another service, e.g. CUPS printing). These are the stunnel(8) SSL
|
|
redirection and the ssh(1) '-L' port redirection. Because 'localhost'
|
|
is used only users or programs on the same workstation that is
|
|
running SSVNC can connect to these ports, however this includes any
|
|
local users (not just the user running SSVNC.)
|
|
|
|
If the untrusted local user tries to connect to these ports, he may
|
|
succeed by varying degrees to gain access to the remote machine.
|
|
We now list some safeguards one can put in place to try to make this
|
|
more difficult to achieve.
|
|
|
|
It probably pays to have the VNC server require a password, even
|
|
though there has already been SSL or SSH authentication (via
|
|
certificates or passwords). In general if the VNC Server requires
|
|
SSL authentication of the viewer that helps, unless the untrusted
|
|
local user has gained access to your SSVNC certificate keys.
|
|
|
|
If the VNC server is configured to only allow one viewer connection
|
|
at a time, then the window of opportunity that the untrusted local
|
|
user can use is greatly reduced: he might only have a second or two
|
|
between the tunnel being set up and the SSVNC vncviewer connecting
|
|
to it (i.e. if the VNC server only allows a single connection, the
|
|
untrusted local user cannot connect once your session is established).
|
|
Similarly, when you disconnect the tunnel is torn down quickly and
|
|
there is little or no window of opportunity to connect (e.g. x11vnc
|
|
in its default mode exits after the first client disconnects).
|
|
|
|
Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC
|
|
prebuilt 'bundles', a patched stunnel is provided that denies all
|
|
connections after the first one, and exits when the first one closes.
|
|
This is not true if the system installed stunnel(8) is used and is
|
|
not true when using SSVNC on Windows.
|
|
|
|
The following are experimental features that are added to SSVNC to
|
|
improve the situation for the SSL/stunnel and SSH cases. Set them
|
|
via Options -> Advanced -> "STUNNEL Local Port Protections" or
|
|
"SSH Local Port Protections".
|
|
|
|
STUNNEL:
|
|
|
|
1) For SSL tunnelling with stunnel(8) on Unix there is a setting
|
|
'Use stunnel EXEC mode' that will try to exec(2) stunnel
|
|
instead of using a listening socket. This will require using
|
|
the specially modified vncviewer unix viewer provided by SSVNC.
|
|
The mode works well and is currently set as the default.
|
|
Disable it if it causes problems or conflicts.
|
|
|
|
2) For SSL tunnelling with stunnel(8) on Unix there is a setting
|
|
'Use stunnel IDENT check' (experimental) to limit socket
|
|
connections to be from you (this assumes the untrusted local
|
|
user has not become root on your workstation and has modified
|
|
your local IDENT check service; if he has you have much bigger
|
|
problems to worry about...)
|
|
|
|
Neither of the above methods are available on Windows.
|
|
|
|
SSH:
|
|
|
|
1) There is also a simple LD_PRELOAD trick for SSH to limit the
|
|
number of accepted port redirection connections. This makes the
|
|
window of time the untrusted local user can connect to the tunnel
|
|
much smaller. Enable it via Options -> Advanced -> "SSH Local
|
|
Port Protections". You will need to have the lim_accept.so file
|
|
in your SSVNC package. The mode works well and is currently set
|
|
as the default. Disable it if it causes problems or conflicts.
|
|
|
|
The above method is not available on Windows.
|
|
|
|
The main message is to 'Watch your Back' when you connect via the
|
|
SSVNC tunnels and there are users you don't trust on your workstation.
|
|
The same applies to ANY use of SSH '-L' port redirections or outgoing
|
|
stunnel SSL redirection services.
|
|
}
|
|
|
|
set help_prox {
|
|
Here are a number of long sections on all sorts of proxies, Web, SOCKS,
|
|
SSH tunnels/gateways, UltraVNC, Single Click, etc., etc.
|
|
|
|
|
|
Proxies/Gateways:
|
|
|
|
If an intermediate proxy is needed to make the SSL connection
|
|
(e.g. a web gateway out of a firewall) enter it in the "Proxy/Gateway"
|
|
entry box:
|
|
|
|
VNC Host-Display: host:number
|
|
Proxy/Gateway: proxy-host:port
|
|
e.g.:
|
|
VNC Host-Display: far-away.east:0
|
|
Proxy/Gateway: myproxy.west:8080
|
|
|
|
|
|
If the "double proxy" case is required (e.g. coming out of a web
|
|
proxied firewall environment and then INTO a 2nd proxy to ultimately
|
|
reach the VNC server), separate them via a comma, e.g.:
|
|
|
|
VNC Host-Display: far-away:0
|
|
Proxy/Gateway: myproxy.west:8080,myhome.net:443
|
|
|
|
So it goes: viewer -> myproxy.west -> myhome.net -> far-away (VNC)
|
|
|
|
The proxies are assumed to be Web proxies. To use SOCKS proxies:
|
|
|
|
VNC Host-Display: far-away.east:0
|
|
Proxy/Gateway: socks://mysocks.west:1080
|
|
|
|
Use socks5:// to force the SOCKS5 proxy protocol (e.g. for ssh -D).
|
|
|
|
You can prefix web proxies with http:// in SSL mode but it doesn't matter
|
|
since that is the default for a proxy. (NOTE that in SSH or SSH+SSL
|
|
mode you MUST supply the http:// prefix for web proxies because in those
|
|
modes an SSH tunnel is the default proxy type: see the next section.)
|
|
|
|
Note that Web proxies are often configured to ONLY allow outgoing
|
|
connections to ports 443 (HTTPS) and 563 (SNEWS), so you might
|
|
have run the VNC server (or router port redirector) on those ports.
|
|
SOCKS proxies usually have no restrictions on port number.
|
|
|
|
You can chain up to 3 proxies (any combination of web (http://) and
|
|
socks://) by separating them with commas (i.e. first,second,third).
|
|
|
|
Proxies also work for un-encrypted connections ("None" or vnc://, Tip 5)
|
|
|
|
See the ss_vncviewer description and x11vnc FAQ for info on proxies:
|
|
|
|
http://www.karlrunge.com/x11vnc/faq.html#ss_vncviewer
|
|
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy
|
|
|
|
|
|
SSH Proxies/Gateways:
|
|
|
|
Proxy/Gateway also applies to SSH mode, it is a usually a gateway SSH
|
|
machine to log into via ssh that is not the workstation running the
|
|
VNC server. However, Web and SOCKS proxies can also be used (see below).
|
|
|
|
For example if a company had a central login server: "ssh.company.com"
|
|
(accessible from the internet) and the internal workstation with VNC was
|
|
named "joes-pc", then to create an SSH tunnel one could put this in:
|
|
|
|
VNC Host:Display: joes-pc:0
|
|
Proxy/Gateway: ssh.company.com
|
|
|
|
It is OK if the hostname "joes-pc" only resolves inside the firewall.
|
|
|
|
The 2nd leg, from ssh.company.com -> joes-pc is done by a ssh -L
|
|
redir and is not encrypted (but the viewer -> ssh.company.com 1st leg is
|
|
an encrypted tunnel).
|
|
|
|
To SSH encrypt BOTH legs, try the "double SSH gateway" method using
|
|
the "comma" notation:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: ssh.company.com,joes-pc
|
|
|
|
this requires an SSH server also running on joes-pc. So an initial SSH
|
|
login is done to ssh.company.com, then a 2nd SSH is performed (through
|
|
port a redirection of the first) to login straight to joes-pc where
|
|
the VNC server is running.
|
|
|
|
Use username@host (e.g. joe@joes-pc jsmith@ssh.company.com) if the
|
|
user names differ between the various machines.
|
|
|
|
NOTE: On Windows you MUST always supply the username@ because putty's
|
|
plink requires it.
|
|
|
|
|
|
NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
|
|
than 22) you need to use the Proxy/Gateways as well. E.g. something
|
|
like this for port 2222:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: joe@far-away.east:2222
|
|
|
|
On Unix/MacOSX the username@ is not needed if it is the same as on
|
|
the client. This will also work going to a different internal machine,
|
|
e.g. "joes-pc:0" instead of "localhost:0", as in the first example.
|
|
|
|
|
|
A Web or SOCKS proxy can also be used with SSH. Use this if you are
|
|
inside a firewall that prohibits direct connections to remote SSH servers.
|
|
|
|
VNC Host:Display: joe@far-away.east:0
|
|
Proxy/Gateway: http://myproxy.west:8080
|
|
|
|
or for SOCKS:
|
|
|
|
VNC Host:Display: joe@far-away.east:0
|
|
Proxy/Gateway: socks://mysocks.west:1080
|
|
|
|
Use socks5://... to force the SOCKS5 version. Note that the http://
|
|
prefix is REQUIRED for web proxies in SSH or SSH+SSL modes (but it is
|
|
the default proxy type in SSL mode.)
|
|
|
|
You can chain up to 3 proxies (any combination of http://, socks://
|
|
and ssh) by separating them with commas (i.e. first,second,third).
|
|
|
|
Note: the Web and/or SOCKS proxies must come before any SSH gateways.
|
|
|
|
For a non-standard SSH port and a Web or SOCKS proxy try:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: http://myproxy.west:8080,joe@far-away.east:2222
|
|
|
|
Even the "double SSH gateway" method (2 SSH encrypted legs) described
|
|
above works with an initial Web or SOCKS proxy, e.g.:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: socks://mysocks.west:1080,ssh.company.com,joes-pc
|
|
|
|
|
|
|
|
Some Notes on SSH localhost tunnelling with SSH options
|
|
NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file:
|
|
|
|
Warning: Note that for proxy use with ssh(1), tunnels going through
|
|
'localhost' are used. This means ssh(1) thinks the remote hostname is
|
|
'localhost', which may cause collisions and confusion when storing
|
|
and checking SSH keys.
|
|
|
|
By default on Unix when a 'localhost' ssh host is involved the
|
|
ssh option -o NoHostAuthenticationForLocalhost=yes is applied (see
|
|
ssh_config(1) for details.) This avoids the warnings and ssh refusing
|
|
to connect, but it reduces security. A man in the middle attack may
|
|
be possible. SSVNC prints out a warning in the terminal every time
|
|
the NoHostAuthenticationForLocalhost option is used.
|
|
|
|
On Unix to disable the use of NoHostAuthenticationForLocalhost set the env.
|
|
variable SSVNC_SSH_LOCALHOST_AUTH=1. This may induce extra ssh(1) dialogs.
|
|
|
|
On Unix a MUCH SAFER and more convenient way to proceed is to set the
|
|
known hosts option in Options -> Advanced -> 'Private SSH KnownHosts file'
|
|
Then, only for the host in the current profile, a private known_hosts
|
|
file will be used and so there will be no 'localhost' collisions.
|
|
This method is secure (assuming you verify the SSH key fingerprint)
|
|
and avoids the man in the middle attack.
|
|
|
|
On Windows, Putty/Plink is used and does not have the UserKnownHosts
|
|
or NoHostAuthenticationForLocalhost features. Keys are stored in
|
|
the registry as localhost:port pairs and so it is possible to use the
|
|
'Port Slot' option to keep the keys separate to avoid the dialogs and
|
|
also maintain good security.
|
|
|
|
Note that for the "double SSH gateway" method the risk from using
|
|
NoHostAuthenticationForLocalhost is significantly less because the first
|
|
ssh connection does not use the option (it connects directly to the remote
|
|
host) and the second one is only exposed for the leg inside the first
|
|
gateway (but is still vulnerable there when NoHostAuthenticationForLocalhost
|
|
is used.)
|
|
|
|
As with a username that contains a space, use %SPACE (or %TAB) to
|
|
indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com
|
|
|
|
UltraVNC Proxies/Gateways:
|
|
|
|
UltraVNC has a "repeater" tool (http://www.uvnc.com/addons/repeater.html
|
|
and http://koti.mbnet.fi/jtko/) that acts as a VNC proxy. SSVNC can
|
|
work with both mode I and mode II schemes of this repeater.
|
|
|
|
For Unix and MacOS X there is another re-implementation of the
|
|
UltraVNC repeater:
|
|
|
|
http://www.karlrunge.com/x11vnc/ultravnc_repeater.pl
|
|
|
|
So one does not need to run the repeater on a Windows machine.
|
|
|
|
Note that even though the UltraVNC repeater tool is NOT SSL enabled,
|
|
it can nevertheless act as a proxy for SSVNC SSL connections.
|
|
This is because, just as with a Web proxy, the proxy negotiations
|
|
occur before the SSL traffic starts. (There is a separate UltraVNC
|
|
tool, repeater_SSL.exe, that is SSL enabled and is discussed below.)
|
|
|
|
Note: it seems only SSL SSVNC connections make sense with the
|
|
UltraVNC repeater. SSH connections (previous section) do not seem to
|
|
and so are not enabled to (let us know if you find a way to use it.)
|
|
|
|
Unencrypted (aka Direct) SSVNC VNC connections (Vnc:// prefix in
|
|
'VNC Host:Display'; see Tip 5) also work with the UltraVNC repeater.
|
|
|
|
MODE I REPEATER:
|
|
|
|
For the mode I UltraVNC repeater the Viewer initiates the connection
|
|
and passes a string that is the VNC server's IP address (or hostname)
|
|
and port or display to the repeater (the repeater then makes the
|
|
connection to the server host and then exchanges data back and forth.)
|
|
To do this in SSVNC:
|
|
|
|
VNC Host:Display: :0
|
|
Proxy/Gateway: repeater://myuvncrep.west:5900+joes-pc:1
|
|
|
|
Where "myuvncrep.west" is running the UltraVNC repeater and
|
|
"joes-pc:1" is the VNC server the repeater will connect us to.
|
|
|
|
Note here that the VNC Host:Display can be anything because it is
|
|
not used; we choose :0. You cannot leave VNC Host:Display empty.
|
|
|
|
The Proxy/Gateway format is repeater://proxy:port+vncserver:display.
|
|
The string after the "+" sign is passed to the repeater server for
|
|
it to interpret (and so does not have to be the UltraVNC repeater;
|
|
you could create your own if you wanted to.) For this example,
|
|
instead of joes-pc:1 it could be joes-pc:5901 or 192.168.1.4:1,
|
|
192.168.1.4:5901, etc.
|
|
|
|
If you do not supply a proxy port, then the default 5900 is assumed,
|
|
e.g. use repeater://myuvncrep.west+joes-pc:1 for port 5900 on
|
|
myuvncrep.west then connecting to port 5901 on joes-pc.
|
|
|
|
X11VNC: For mode I operation the VNC server x11vnc simply runs as
|
|
a normal SSL/VNC server:
|
|
|
|
x11vnc -ssl SAVE
|
|
|
|
because the repeater will connect to it as a VNC client would.
|
|
For mode II operation additional options are needed (see below.)
|
|
|
|
|
|
MODE II REPEATER:
|
|
|
|
For the mode II repeater both the VNC viewer and VNC server initiate
|
|
TCP connections to the repeater proxy. In this case they pass a string
|
|
that identifies their mutual connection via "ID:NNNN", for example:
|
|
|
|
VNC Host:Display: :0
|
|
Proxy/Gateway: repeater://myuvncrep.west:5900+ID:2345
|
|
|
|
again, the default proxy port is 5900 if not supplied. And we need
|
|
to supply a placeholder display ":0".
|
|
|
|
The fact that BOTH the VNC viewer and VNC server initiate outgoing
|
|
TCP connections to the repeater makes some things tricky, especially
|
|
for the SSL aspect. In SSL one side takes the 'client' role and
|
|
the other side must take the 'server' role. These roles must be
|
|
coordinated correctly or otherwise the SSL handshake will fail.
|
|
|
|
We now describe two scenarios: 1) SSVNC in Listening mode with STUNNEL
|
|
in 'SSL server' role; and 2) SSVNC in Forward mode with STUNNEL in
|
|
'SSL client' role. For both cases we show how the corresponding
|
|
VNC server x11vnc would be run.
|
|
|
|
SSVNC Listening mode / STUNNEL 'SSL server' role:
|
|
|
|
By default, when using SSL over a reverse connection the x11vnc VNC
|
|
server will take the 'SSL client' role. This way it can connect to a
|
|
standard STUNNEL (SSL server) redirecting connections to a VNC viewer
|
|
in Listen mode. This is how SSVNC with SSL is normally intended to
|
|
be used for reverse connections (i.e. without the UltraVNC Repeater.)
|
|
|
|
To do it this way with the mode II UltraVNC Repeater; you set
|
|
Options -> Reverse VNC Connection, i.e. a "Listening Connection".
|
|
You should disable 'Verify All Certs' unless you have already
|
|
saved the VNC Server's certificate to Accepted Certs. Or you can
|
|
set ServerCert to the saved certificate. Then click 'Listen'.
|
|
In this case an outgoing connection is made to the UltraVNC
|
|
repeater, but everything else is as for a Reverse connection.
|
|
|
|
Note that in Listening SSL mode you must supply a MyCert or use the
|
|
"listen.pem" one you are prompted by SSVNC to create.
|
|
|
|
X11VNC command:
|
|
|
|
x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345
|
|
|
|
|
|
SSVNC Forward mode / STUNNEL 'SSL client' role:
|
|
|
|
x11vnc 0.9.10 and later can act in the 'SSL server' role for Reverse
|
|
connections (i.e. as it does for forward connections.) Set these
|
|
x11vnc options: '-env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -sslonly'
|
|
|
|
The -sslonly option is to prevent x11vnc from thinking the delay in
|
|
connection implies VeNCrypt instead of VNC over SSL. With x11vnc
|
|
in X11VNC_DISABLE_SSL_CLIENT_MODE mode, you can then have SSVNC make
|
|
a regular forward connection to the UltraVNC repeater.
|
|
|
|
Note that SSVNC may attempt to do a 'Fetch Cert' action in forward
|
|
connection mode to either retrieve the certificate or probe for
|
|
VeNCrypt and/or ANONDH. After that 'Fetch Cert' is done the
|
|
connection to the UltraVNC repeater will be dropped. This is a
|
|
problem for the subsequent real VNC connection. You can disable
|
|
'Verify All Certs' AND also set 'Do not Probe for VeNCrypt'
|
|
to avoid the 'Fetch Cert' action. Or, perhaps better, add to
|
|
x11vnc command line '-connect_or_exit repeater://... -loop300,2'
|
|
(in addition to the options in the previous paragraphs.) That way
|
|
x11vnc will reconnect once to the Repeater after the 'Fetch Cert'
|
|
action. Then things should act pretty much as a normal forward
|
|
SSL connection.
|
|
|
|
X11VNC 0.9.10 command (split into two lines):
|
|
|
|
x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345 \
|
|
-env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -loop300,2 -sslonly
|
|
|
|
We recommend using "SSVNC Forward mode / STUNNEL 'SSL client' role"
|
|
if you are connecting to x11vnc 0.9.10 or later. Since this does
|
|
not use Listen mode it should be less error prone and less confusing
|
|
and more compatible with other features. Be sure to use all of
|
|
the x11vnc options in the above command line. To enable VeNCrypt,
|
|
replace '-sslonly' with '-vencrypt force'. If you do not indicate
|
|
them explicitly to SSVNC, SSVNC may have to probe multiple times for
|
|
VeNCrypt and/or ANONDH. So you may need '-loop300,4' on the x11vnc
|
|
cmdline so it will reconnect to the UltraVNC repeater 3 times.
|
|
|
|
|
|
Note that for UNENCRYPTED (i.e. direct) SSVNC connections (see vnc://
|
|
in Tip 5) using the UltraVNC Repeater mode II there is no need to
|
|
use a reverse "Listening connection" and so you might as well use
|
|
a forward connection.
|
|
|
|
For Listening connections, on Windows after the VNC connection you
|
|
MUST manually terminate the listening VNC Viewer (and connect again
|
|
if desired.) Do this by going to the System Tray and terminating
|
|
the Listening VNC Viewer. Subsequent connection attempts using the
|
|
repeater will fail unless you do this and restart the Listen.
|
|
|
|
On Unix and MacOS X after the VNC connection the UltraVNC repeater
|
|
proxy script will automatically restart and reconnect to the repeater
|
|
for another connection. So you do not need to manually restart it.
|
|
To stop the listening, kill the listening VNC Viewer with Ctrl-C.
|
|
|
|
In the previous sections it was mentioned one can chain up to 3
|
|
proxies together by separating them with commas: proxy1,proxy2,proxy3.
|
|
Except where explicitly noted below this should work for "repeater://..."
|
|
as the final proxy. E.g. you could use a web proxy to get out of a
|
|
firewall, and then connect to a remote repeater.
|
|
|
|
The UltraVNC SSL enabled repeater_SSL.exe is discussed below.
|
|
|
|
|
|
UltraVNC Single Click:
|
|
|
|
UltraVNC has Single Click (SC) Windows VNC servers that allow naive
|
|
users to get them running very easily (a EXE download and a few
|
|
mouse clicks). See http://sc.uvnc.com/ for details on how to create
|
|
these binaries. Also there is a how-to here:
|
|
http://www.simply-postcode-lookup.com/SingleClickUltraVNC/SingleClickVNC.htm
|
|
|
|
The SC EXE is a VNC *server* that starts up a Reverse VNC connection
|
|
to a Listening Viewer (e.g. the viewer address/port/ID is hardwired
|
|
into the SC EXE). So SC is not really a proxy, but it can be used
|
|
with UltraVNC repeater proxies and so we describe it here.
|
|
|
|
One important point for SC III binary creation: do NOT include
|
|
"-id N" in the helpdesk.txt config file. This is because the with
|
|
SSVNC the Ultra VNC repeater IS NOT USED (see below for how to
|
|
use it). Use something like for helpdesk.txt:
|
|
|
|
[TITLE]
|
|
My UltraVNC SC III
|
|
|
|
[HOST]
|
|
Internet Support XYZ
|
|
-sslproxy -connect xx.xx.xx.xx:5500 -noregistry
|
|
|
|
(replace xx.xx.xx.xx with IP address or hostname of the SSVNC machine.)
|
|
|
|
The Unix SSVNC vncviewer supports the both the unencrypted "SC I"
|
|
mode and the SSL encrypted "SC III" mode. For both cases SSVNC
|
|
must be run in Listening mode (Options -> Reverse VNC Connection)
|
|
|
|
For SC I, enable Reverse VNC Connection and put Vnc://0 (see Tip 5
|
|
below) in the VNC Host:Display to disable encryption (use a different
|
|
number if you are not using the default listening port 5500).
|
|
Then click on the "Listen" button and finally have the user run your
|
|
Single Click I EXE.
|
|
|
|
BTW, we used this for a SC I helpdesk.txt:
|
|
|
|
[TITLE]
|
|
My UltraVNC SC I
|
|
|
|
[HOST]
|
|
Internet Support XYZ
|
|
-connect xx.xx.xx.xx:5500 -noregistry
|
|
|
|
For SC III (SSL), enable Reverse VNC Connection and then UNSET "Verify
|
|
All Certs" (this is required). Let the VNC Host:Display be ":0"
|
|
(use a different number if you are not using the default listening
|
|
port 5500). Then click on the "Listen" button and finally have the
|
|
user run your Single Click III EXE.
|
|
|
|
Note that in Listening SSL mode you MUST supply a MyCert or use the
|
|
"listen.pem" one you are prompted by SSVNC to create.
|
|
|
|
|
|
UltraVNC repeater_SSL.exe proxy:
|
|
|
|
For repeater_SSL.exe SSL usage, with Single Click III or otherwise
|
|
(available at http://www.uvnc.com/pchelpware/SCIII/index.html)
|
|
it helps to realize that the ENTIRE connection is SSL encrypted,
|
|
even the proxy host:port/ID:NNNN negotiation, and so a different
|
|
approach needs to be taken from that described above in 'UltraVNC
|
|
Proxies/Gateways'. In this case do something like this:
|
|
|
|
VNC Host:Display: :0
|
|
Proxy/Gateway: sslrepeater://myuvncrep.west:443+ID:2345
|
|
|
|
The sslrepeater:// part indicates the entire ID:XYZ negotiation must
|
|
occur inside the SSL tunnel. Listening mode is not required in this
|
|
case: a forward VNC connection works fine (and is recommended).
|
|
As before, the ":0" is simply a placeholder and is not used.
|
|
Note that the UltraVNC repeater_SSL.exe listens on port 443 (HTTPS),
|
|
(it is not clear that it can be modified to use another port.)
|
|
|
|
Non-ID connections sslrepeater://myuvncrep.west:443+host:disp also
|
|
work, but the 2nd leg repeater <-> host:disp must be unencrypted.
|
|
The first leg SSVNC <-> repeater is, however, SSL encrypted.
|
|
|
|
sslrepeater:// only works on Unix or MacOSX using the provided
|
|
SSVNC vncviewer. The modified viewer is needed; stock VNC viewers
|
|
will not work. Also, proxy chaining (bouncing off of more than one
|
|
proxy) currently does not work for repeater_SSL.exe.
|
|
|
|
|
|
VeNCrypt is treated as a proxy:
|
|
|
|
SSVNC supports the VeNCrypt VNC security type. You will find out more
|
|
about this security type in the other parts of the Help documentation.
|
|
In short, it does a bit of plain-text VNC protocol negotiation before
|
|
switching to SSL/TLS encryption and authentication.
|
|
|
|
SSVNC implements its VeNCrypt support as final proxy in a chain
|
|
of proxies. You don't need to know this or specify anything, but
|
|
it is good to know since it uses up one of the 3 proxies you are
|
|
allowed to chain together. If you watch the command output you will
|
|
see the vencrypt:// proxy item.
|
|
|
|
You can specify that a VNC server uses VeNCrypt (Options -> Advanced)
|
|
or you can let SSVNC try to autodetect VeNCrypt.
|
|
|
|
|
|
IPv6 can be treated as a proxy for UN-ENCRYPTED connections:
|
|
|
|
Read Tip 20 about SSVNC's IPv6 (128 bit IP addresses) support.
|
|
In short, because stunnel and ssh support IPv6 hostnames and
|
|
addresses, SSVNC does too without you needing to do anything.
|
|
|
|
However, in some rare usage modes you will need to specify the IPv6
|
|
server destination in the Proxy/Gateway entry box. The only case
|
|
this appears to be needed is when making an un-encrypted connection
|
|
to an IPv6 VNC server. In this case neither stunnel nor ssh are
|
|
used and you need to specify something like this:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: ipv6://2001:4860:b009::68:5900
|
|
|
|
and then select 'None' as the encryption type. Note that the above
|
|
'localhost:0' setting can be anything; it is basically ignored.
|
|
|
|
Note that on Unix, MacOSX, and Windows un-encrypted ipv6 connections
|
|
are AUTODETECTED and so you likely NEVER need to supply ipv6://
|
|
Only try it if you encounter problems. Also note that the ipv6://
|
|
proxy type does not work on Windows, so only the autodetection is
|
|
available there.
|
|
|
|
Note that if there is some other proxy, e.g. SOCKS or HTTP and that
|
|
proxy server is an IPv6 host (or will connect you to one) then any
|
|
sort of connection through that proxy will work OK: un-encrypted as
|
|
well as SSL or SSH connections, etc.
|
|
|
|
Unencrypted connection is the only special case where you may need
|
|
to specify an ipv6:// proxy. If you find another use let us know.
|
|
|
|
See Tip 20 for more info.
|
|
}
|
|
|
|
set help_tips {
|
|
Tips and Tricks:
|
|
|
|
Table of Contents:
|
|
|
|
1) Connect to Non-Standard SSH port.
|
|
2) Reverse VNC connections (Listening)
|
|
3) Global options in ~/.ssvncrc
|
|
4) Fonts
|
|
5) vnc://host for un-encrypted connection
|
|
6) Home directory for memory stick usage, etc.
|
|
7) vncs:// vncssl:// vnc+ssl:// vnc+ssh:// URL-like prefixes
|
|
8) sshvnc / -ssh SSH only GUI
|
|
9) tsvnc / -ts Terminal services only GUI (SSH+x11vnc)
|
|
10) 2nd GUI window on Unix/MacOSX
|
|
11) Ctrl-L or Button3 to Load profile
|
|
12) SHELL command or Ctrl-S for SSH terminal w/o VNC
|
|
13) KNOCK command for port-knock sequence
|
|
14) Unix/MacOSX general SSL redirector (not just VNC)
|
|
15) Environment variables
|
|
16) Bigger "Open File" dialog window
|
|
17) Unix/MacOSX extra debugging output
|
|
18) Dynamic VNC Server Port determination with SSH
|
|
19) No -t ssh cmdline option for older sshd
|
|
20) IPv6 support.
|
|
|
|
1) To connect in SSH-Mode to a server running SSH on a non-standard
|
|
port (22 is the standard port) you need to use the Proxy/Gateway
|
|
setting. The following is from the Proxies Help panel:
|
|
|
|
NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
|
|
than 22) you need to use the Proxy/Gateways as well. E.g. something
|
|
like this for port 2222:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: joe@far-away.east:2222
|
|
|
|
The username@ is not needed if it is the same as on the client. This
|
|
will also work going to a different internal machine, e.g. "joes-pc:0"
|
|
instead of "localhost:0", as in the first example.
|
|
|
|
2) Reverse VNC connections (Listening) are possible as well.
|
|
In this case the VNC Server initiates the connection to your
|
|
waiting (i.e. listening) SSVNC viewer.
|
|
|
|
Go to Options and select "Reverse VNC connection". In the 'VNC
|
|
Host:Display' entry box put in the number (e.g. "0" or ":0", or
|
|
":1", etc) that corresponds to the Listening display (0 -> port
|
|
5500, 1 -> port 5501, etc.) you want to use. Then clicking on
|
|
'Listen' puts your SSVNC viewer in a "listening" state on that
|
|
port number, waiting for a connection from the VNC Server.
|
|
|
|
On Windows or using a 3rd party VNC Viewer multiple, simultaneous
|
|
reverse connections are always enabled. On Unix/MacOSX with the
|
|
provided ssvncviewer they are disabled by default. To enable them:
|
|
Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Connections
|
|
|
|
Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
|
|
only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0
|
|
This also works for UN-encrypted reverse connections as well ('None').
|
|
|
|
See the Options Help for more info.
|
|
|
|
3) You can put global options in your ~/.ssvncrc file (ssvnc_rc on
|
|
Windows). Currently they are:
|
|
|
|
Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
|
|
the application start up in the given mode.
|
|
|
|
desktop_type=wmaker (e.g.) to switch the default Desktop Type.
|
|
|
|
desktop_size=1280x1024 (e.g.) to switch the default Desktop Size.
|
|
|
|
desktop_depth=24 (e.g.) to switch the default Desktop Color Depth
|
|
|
|
xserver_type=Xdummy (e.g.) to switch the default X Server Type.
|
|
|
|
(The above 4 settings apply only to the Terminal Services Mode.)
|
|
|
|
noenc=1 (same as the -noenc option for a 'No Encryption' option)
|
|
noenc=0 (do not show the 'No Encryption' option)
|
|
|
|
killstunnel=1 (same as -killstunnel), on Windows automatically kills
|
|
the STUNNEL process when the viewer exits. Disable via killstunnel=0
|
|
and -nokillstunnel.
|
|
|
|
ipv6=0 act as though IPv6 was not detected.
|
|
ipv6=1 act as though IPv6 was detected.
|
|
|
|
cotvnc=1 have the default vncviewer on Mac OS X be the Chicken of
|
|
the VNC. By default the included ssvnc X11 vncviewer is used
|
|
(requires Mac OS X X11 server to be running.)
|
|
|
|
mycert=file (same as -mycert file option). Set your default MyCert
|
|
to "file". If file does not exist ~/.vnc/certs/file is used.
|
|
|
|
cacert=file (same as -cacert file option). Set your default ServerCert
|
|
to "file". If file does not exist ~/.vnc/certs/file is used. If
|
|
file is "CA" then ~/.vnc/certs/CA/cacert.pem is used.
|
|
|
|
crl=file (same as -crl file option). Set your default CRL File
|
|
to "file". If file does not exist ~/.vnc/certs/file is used.
|
|
|
|
Prefix any of these cert/key files with "FORCE:" to make them
|
|
immutable, e.g. "cacert=FORCE:CA".
|
|
|
|
You can set any environment variable in ~/.ssvncrc by using a line
|
|
like env=VAR=value, for example: env=SSVNC_FINISH_SLEEP=2
|
|
|
|
To change the fonts (see Tip 4 below for examples):
|
|
|
|
font_default=tk-font-name (sets the font for menus and buttons)
|
|
font_fixed=tk-font-name (sets the font for help text)
|
|
|
|
4) Fonts: To change the tk fonts, set these environment variables
|
|
before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED.
|
|
For example:
|
|
|
|
% env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc
|
|
% env SSVNC_FONT_FIXED='courier -14' ssvnc
|
|
|
|
or set both of them at once. You can also set 'font_default' and
|
|
'font_fixed' in your ~/.ssvncrc. E.g.:
|
|
|
|
font_default=helvetica -16 bold
|
|
font_fixed=courier -12
|
|
|
|
5) If you want to make a Direct VNC connection, WITH *NO* SSL OR
|
|
SSH ENCRYPTION or authentication, use the "vnc://" prefix in the
|
|
VNC Host:Display entry box, e.g. "vnc://far-away.east:0" This
|
|
also works for reverse connections, e.g. vnc://0
|
|
|
|
Use Vnc:// (i.e. capital 'V') to avoid being prompted if you are
|
|
sure you want no encryption. For example, "Vnc://far-away.east:0"
|
|
Shift+Ctrl-E in the entry box is a short-cut to add or remove
|
|
the prefix "Vnc://" from the host:disp string.
|
|
|
|
You can also run ssvnc with the '-noenc' cmdline option (now
|
|
the default) to have a check option 'None' that lets you turn off
|
|
Encryption (and profiles will store this setting). Pressing Ctrl-E
|
|
on the main panel is a short-cut to toggle between the -noenc 'No
|
|
Encryption' mode and normal mode. The option "Show 'No Encryption'
|
|
Option" under Options also toggles it.
|
|
|
|
The '-enc' option disables the button (and so makes it less obvious
|
|
to naive users how to disable encryption.)
|
|
|
|
Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e.
|
|
the 'No Encryption' option ('None') is shown by default. When
|
|
you select 'None' you do not need to supply the "vnc://" prefix.
|
|
To disable the button supply the '-enc' cmdline option.
|
|
|
|
Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=1 in your environment is
|
|
the same as -noenc. You can also put noenc=1 in your ~/.ssvncrc file.
|
|
|
|
Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=0 in your environment is
|
|
the same as -enc. You can also put noenc=0 in your ~/.ssvncrc file.
|
|
|
|
Please be cautious/thoughtful when you make a VNC connection with
|
|
encryption disabled. You may send sensitive information (e.g. a
|
|
password) over the network that can be sniffed.
|
|
|
|
It is also possible (although difficult) for someone to hijack an
|
|
existing unencrypted VNC session.
|
|
|
|
Often SSVNC is used to connect to x11vnc where the Unix username and
|
|
password is sent over the channel. It would be a very bad idea to
|
|
let that data be sent over an unencrypted connection! In general,
|
|
it is not wise to have a plaintext VNC connection.
|
|
|
|
Note that even the VNC Password challenge-response method (the password
|
|
is not sent in plaintext) leaves your VNC password susceptible to a
|
|
dictionary attack unless encryption is used to hide it.
|
|
|
|
So (well, before we made the button visible by default!) we forced
|
|
you to learn about and supply the "vnc://" or "Vnc://" prefix to
|
|
the host:port or use -noenc or the "Show 'No Encryption' Option"
|
|
to disable encryption. This is a small hurdle, but maybe someone
|
|
will think twice. It is a shame that VNC has been around for
|
|
over 10 years and still does not have built-in strong encryption.
|
|
|
|
Note the Vnc:// or vnc:// prefix will be stored in any profile that
|
|
you save so you do not have to enter it every time.
|
|
|
|
Set the env var SSVNC_NO_ENC_WARN=1 to skip the warning prompts the
|
|
same as the capitalized Vnc:// does.
|
|
|
|
6) Mobile USB memory stick / flash drive usage: You can unpack
|
|
ssvnc to a flash drive for impromptu usage (e.g. from a friends
|
|
computer).
|
|
|
|
If you create a directory "Home" in the toplevel ssvnc directory,
|
|
then that will be the default location for your VNC profiles
|
|
and certs. So they follow the drive this way. If you run like
|
|
this: "ssvnc ." or "ssvnc.exe ." the "Home" directory will be
|
|
created for you.
|
|
|
|
WARNING: if you use ssvnc from an "Internet Cafe", i.e. an
|
|
untrusted computer, an unscrupulous person may be capturing
|
|
keystrokes, etc.!
|
|
|
|
You can also set the SSVNC_HOME env. var. to point to any
|
|
directory you want. It can be set after starting ssvnc by putting
|
|
HOME=/path/to/dir in the Host:Display box and clicking "Connect".
|
|
|
|
For a Windows BAT file to get the "Home" directory correct
|
|
something like this might be needed:
|
|
|
|
cd \ssvnc\Windows
|
|
start \ssvnc\Windows\ssvnc.exe
|
|
|
|
7) In the VNC Host:Display entry you can also use these "URL-like"
|
|
prefixes:
|
|
|
|
vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL
|
|
|
|
and
|
|
|
|
vncssh://host:0, vnc+ssh://host:0 for SSH
|
|
|
|
There is no need to toggle the SSL/SSH setting. These also work
|
|
from the command line, e.g.: ssvnc vnc+ssh://mymachine:10
|
|
|
|
8) If you want this application to be SSH only, then supply the
|
|
command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1.
|
|
|
|
Then no GUI elements specific to SSL will appear (the
|
|
documentation wills still refer to the SSL mode, however).
|
|
To convert a running app to ssh-only select "Mode: SSH-Only"
|
|
in Options.
|
|
|
|
The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up
|
|
automatically this way.
|
|
|
|
Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=sshvnc"
|
|
to have the tool always start up in that mode.
|
|
|
|
9) For an even simpler "Terminal Services" mode use "tsvnc" or
|
|
"tsvnc.bat" (or "-ts" option). This mode automatically launches
|
|
x11vnc on the remote side to find or create your Desktop session
|
|
(usually the Xvfb X server). So x11vnc must be available on the
|
|
remote server machines under "Terminal Services" mode.
|
|
|
|
From a full ssvnc you can press Ctrl-h to go into ssh-only mode
|
|
and Ctrl-t to toggle between "tsvnc" and "ssvnc" modes. The
|
|
Options Mode menu also let you switch.
|
|
|
|
Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
|
|
to have the tool always start up in that mode.
|
|
|
|
10) On Unix to get a 2nd GUI (e.g. for a 2nd connection) press Ctrl-N
|
|
on the GUI. If only the xterm window is visible you can press
|
|
Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you
|
|
will have to manually Start a new one: Start -> Run ..., etc.
|
|
|
|
11) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right
|
|
mouse button on the main GUI will invoke the Load dialog.
|
|
|
|
Pressing Ctrl-O on the main GUI will bring up the Options Panel.
|
|
Pressing Ctrl-A on the main GUI will bring up the Advanced Options.
|
|
|
|
12) If you use "SHELL" for the "Remote SSH Command" (or in the display
|
|
line: "user@hostname cmd=SHELL") then you get an SSH shell only:
|
|
no VNC viewer will be launched. On Windows "PUTTY" will try
|
|
to use putty.exe (better terminal emulation than plink.exe).
|
|
|
|
A ShortCut for this is Ctrl-S with user@hostname in the entry box.
|
|
|
|
13) If you use "KNOCK" for the "Remote SSH Command" (or in the display
|
|
line "user@hostname cmd=KNOCK") then only the port-knocking is done.
|
|
|
|
A ShortCut for this is Ctrl-P with hostname the entry box.
|
|
|
|
If it is KNOCKF, i.e. an extra "F", then the port-knocking
|
|
"FINISH" sequence is sent, if any. A ShortCut for this
|
|
Shift-Ctrl-P as long as hostname is present.
|
|
|
|
14) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no
|
|
VNC), put the desired host:port in VNC Host:Display (use a
|
|
negative port value if it is to be less than 200), then go to
|
|
Options -> Advanced -> Change VNC Viewer. Change the "viewer"
|
|
command to be "xmessage OK" or "xmessage <port>" (or sleep) where
|
|
port is the desired local listening port. Then click Connect.
|
|
If you didn't set the local port look for it in the terminal output.
|
|
|
|
On Windows set 'viewer' to "NOTEPAD" or similar; you can't
|
|
control the port though. It is usually 5930, 5931, ... Watch
|
|
the messages or look at the stunnel log.
|
|
|
|
15) Tricks with environment variables:
|
|
|
|
You can change the X DISPLAY variable by typing DISPLAY=... into
|
|
VNC Host:Display and hitting Return or clicking Connect. Same
|
|
for HOME=. On Mac, you can set DYLD_LIBRARY_PATH=... too.
|
|
It should propagate down the viewer.
|
|
|
|
Setting SLEEP=n increases the amount of time waited before
|
|
starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does
|
|
this (and also Sleep: Option setting) Setting FINISH=n sets the
|
|
amount of time slept before the Terminal window exits on Unix
|
|
and MacOS X. (same as SSVNC_FINISH_SLEEP env. var.)
|
|
|
|
Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY
|
|
DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP
|
|
FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE,
|
|
SSH_ONLY, TS_ONLY, NO_DELETE, BAT_SLEEP, IPV6/SSVNC_IPV6=0 or 1.
|
|
See below for more info. (the ones joined by "/" are equivalent
|
|
names, and the latter can be set as an env. var. as well.)
|
|
|
|
After you set the parameter, clear out the 'VNC Host:Display'
|
|
entry and replace it with the actual host and display number.
|
|
|
|
To replace the xterm terminal where most of the external commands
|
|
are run set SSVNC_XTERM_REPLACEMENT to a command that will run
|
|
a command in a terminal. I.e.: "$SSVNC_XTERM_REPLACEMENT cmd"
|
|
will run cmd. If present, %GEOMETRY is expanded to a desired
|
|
+X+Y geometry. If present, %TITLE is expanded to a desired title.
|
|
Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e'
|
|
SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e'
|
|
SSVNC_XTERM_REPLACEMENT='konsole -e'
|
|
|
|
More info: EXTRA_SLEEP: seconds of extra sleep in scripts;
|
|
FINISH_SLEEP: final extra sleep at end; DEBUG_NETSTAT put up a
|
|
window showing what netstat reports; NO_DELETE: do not delete tmp
|
|
bat files on Windows (for debugging); BAT_SLEEP: sleep this many
|
|
seconds at the end of each Windows bat file (for debugging.)
|
|
|
|
You can also set any environment variable by entering in something
|
|
like ENV=VAR=VAL e.g. ENV=SSH_AUTH_SOCK=/tmp/ssh-BF2297/agent.2297
|
|
Use an empty VAL to unset the variable.
|
|
|
|
There are also a HUGE number of env. vars. that apply to the Unix
|
|
and MacOS X wrapper script 'ss_vncviewer' and/or the ssvncviewer
|
|
binary. See Options -> Advanced -> Unix ssvncviewer -> Help for
|
|
all of them.
|
|
|
|
16) On Unix you can make the "Open File" and "Save File" dialogs
|
|
bigger by setting the env. var. SSVNC_BIGGER_DIALOG=1 or
|
|
supplying the -bigger option. If you set it to a Width x Height,
|
|
e.g. SSVNC_BIGGER_DIALOG=500x200, that size will be used.
|
|
|
|
17) On Unix / MacOSX to enable debug output you can set these env.
|
|
vars to 1: SSVNC_STUNNEL_DEBUG, SSVNC_VENCRYPT_DEBUG, and
|
|
SS_DEBUG (very verbose)
|
|
|
|
18) Dynamic VNC Server Port determination and redirection: If you
|
|
are running SSVNC on Unix and are using SSH to start the remote
|
|
VNC server and the VNC server prints out the line "PORT=NNNN"
|
|
to indicate which dynamic port it is using (x11vnc does this),
|
|
then if you prefix the SSH command with "PORT=" SSVNC will watch
|
|
for the PORT=NNNN line and uses ssh's built in SOCKS proxy
|
|
(ssh -D ...) to connect to the dynamic VNC server port through
|
|
the SSH tunnel. For example:
|
|
|
|
VNC Host:Display user@somehost.com
|
|
Remote SSH Command: PORT= x11vnc -find -nopw
|
|
|
|
or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..."
|
|
|
|
There is also code to detect the display of the regular Unix
|
|
vncserver(1). It extracts the display (and hence port) from
|
|
the lines "New 'X' desktop is hostname:4" and also
|
|
"VNC server is already running as :4". So you can use
|
|
something like:
|
|
|
|
PORT= vncserver; sleep 15
|
|
or: PORT= vncserver :4; sleep 15
|
|
|
|
the latter is preferred because when you reconnect with it will
|
|
find the already running one. The former one will keep creating
|
|
new X sessions if called repeatedly.
|
|
|
|
On Windows if PORT= is supplied SOCKS proxying is not used, but
|
|
rather a high, random value of the VNC port is chosen (e.g. 8453)
|
|
and assumed to be free, and is passed to x11vnc's -rfbport option.
|
|
This only works with x11vnc (not vncserver).
|
|
|
|
19) On Unix if you are going to an older SSH server (e.g. Solaris 10),
|
|
you will probably need to set the env. var. SS_VNCVIEWER_NO_T=1
|
|
to disable the ssh "-t" option being used (that can prevent the
|
|
command from being run).
|
|
|
|
20) SSVNC is basically a wrapper for the stunnel and ssh programs,
|
|
and because those two programs have good IPv6 support SSVNC will
|
|
for most usage modes support it as well. IPv6 is 128 bit internet
|
|
addresses (as opposed to IPv4 with its 32 bit xxx.yyy.zzz.nnn IPs.
|
|
|
|
So for basic SSL and SSH connections if you type in an IPv6 IP
|
|
address, e.g. '2001:4860:b009::68', or a hostname with only an
|
|
IPv6 lookup, e.g. ipv6.l.google.com, the connection will work
|
|
because stunnel and ssh handle these properly.
|
|
|
|
Note that you often need to supply a display number or port after
|
|
the address so put it, e.g. ':0' at the end: 2001:4860:b009::68:0
|
|
You can also use the standard notation [2001:4860:b009::68]:0
|
|
that is more clear. You MUST specify the display if you use
|
|
the IPv6 address notation (but :0 is still the default for a
|
|
non-numeric hostname string.)
|
|
|
|
IPv4 addresses encoded in IPv6 notation also work, e.g.
|
|
::ffff:192.168.1.100 should work for the most part.
|
|
|
|
SSVNC on Unix and MacOSX also has its own Proxy helper tool
|
|
(pproxy) This script has been modified to handle IPv6 hostnames
|
|
and addresses as long as the IO::Socket::INET6 Perl module
|
|
is available. On Windows the relay6.exe tool is used.
|
|
|
|
So for the most part IPv6 should work without you having to do
|
|
anything special. However, for rare usage, the proxy helper tool
|
|
can also treat and IPv6 address as a special sort of 'proxy'.
|
|
So in the entry Proxy/Gateway you can include ipv6://host:port
|
|
and the IPv6 host will simply be connected to and the data
|
|
transferred. In this usage mode, set the VNC Host:Display
|
|
to anything, e.g. 'localhost:0'; it is ignored if the ipv6://
|
|
endpoint is specified as a proxy. Need for ipv6:// usage proxy
|
|
should be rare.
|
|
|
|
Note that for link local (not global) IPv6 addresses you may
|
|
need to include the network interface at the end of the address,
|
|
e.g. fe80::a00:20ff:fefd:53d4%eth0
|
|
|
|
Note that one can use a 3rd party VNC Viewer with SSVNC (see
|
|
Options -> Advanced -> Change VNC Viewer.) IPv6 will work for
|
|
them as well even if they do not support IPv6.
|
|
|
|
IPv6 support on Unix, MacOSX, and Windows is essentially complete
|
|
for all types of connections (including proxied, unencrypted and
|
|
reverse connections.) Let us know if you find a scenario that
|
|
does not work (see the known exception for putty/plink below.)
|
|
|
|
You can set ipv6=0 in your ssvncrc, then no special relaying for
|
|
IPv6 will be done (do this if there are problems or slowness in
|
|
trying to relay ipv6 and you know you will not connect to any
|
|
such hosts.) Set ipv6=1 to force the special processing even if
|
|
IPv6 was not autodetected. To change this dynamically, you also
|
|
enter IPV6=... in the VNC Host:Display entry box and press Enter.
|
|
Also on Unix or MacOSX you can set the env. var. SSVNC_IPV6=0
|
|
to disable the wrapper script from checking if hosts have ipv6
|
|
addresses (this is the same as setting ipv6=0 in ssvncrc or by
|
|
the setting ipv6 in the Entry box.)
|
|
|
|
On Windows plink.exe (SSH client) currently doesn't work for
|
|
IPv6 address strings (e.g. 2001:4860:b009::68) but it does work
|
|
for hostname strings that resolve to IPv6 addresses.
|
|
|
|
Note that one can make a home-brew SOCKS5 ipv4-to-ipv6 gateway
|
|
proxy using ssh like this:
|
|
|
|
ssh -D '*:1080' localhost "printf 'Press Enter to Exit: '; read x"
|
|
|
|
then specify a proxy like socks5://hostname:1080 where hostname
|
|
is the machine running the above ssh command. Add '-v' to the
|
|
ssh cmdline for verbose output. See also the x11vnc inet6to4 tool
|
|
(a direct ipv4/6 relay, not socks.)
|
|
}
|
|
|
|
global version
|
|
set help_main " SSVNC version: $version\n$help_main"
|
|
set help_misc " SSVNC version: $version\n$help_misc"
|
|
set help_prox " SSVNC version: $version\n$help_prox"
|
|
set help_tips " SSVNC version: $version\n$help_tips"
|
|
|
|
frame .h.w
|
|
button .h.w.b1 -text "Main" -command {help_text main}
|
|
button .h.w.b2 -text "Proxies" -command {help_text prox}
|
|
button .h.w.b3 -text "Misc" -command {help_text misc}
|
|
button .h.w.b4 -text "Tips" -command {help_text tips}
|
|
|
|
pack .h.w.b1 .h.w.b2 .h.w.b3 .h.w.b4 -side left -fill x -expand 1
|
|
|
|
pack .h.w -side bottom -after .h.d -fill x
|
|
|
|
.h.f.t insert end $help_main
|
|
jiggle_text .h.f.t
|
|
}
|
|
|
|
proc help_text {which} {
|
|
global help_main help_misc help_prox help_tips
|
|
set txt ""
|
|
if {$which == "main"} {
|
|
set txt $help_main
|
|
}
|
|
if {$which == "misc"} {
|
|
set txt $help_misc
|
|
}
|
|
if {$which == "prox"} {
|
|
set txt $help_prox
|
|
}
|
|
if {$which == "tips"} {
|
|
set txt $help_tips
|
|
}
|
|
catch {.h.f.t delete 0.0 end; .h.f.t insert end $txt; jiggle_text .h.f.t}
|
|
}
|
|
|
|
proc ssvnc_escape_help {} {
|
|
toplev .ekh
|
|
|
|
scroll_text_dismiss .ekh.f
|
|
|
|
center_win .ekh
|
|
wm title .ekh "SSVNC Escape Keys Help"
|
|
|
|
set msg {
|
|
SSVNC Escape Keys:
|
|
|
|
The Unix SSVNC VNC Viewer, ssvncviewer(1), has an 'Escape Keys'
|
|
mechanism that enables using keystrokes that are bound as 'Hot Keys'
|
|
to specific actions.
|
|
|
|
So, when you have all of the modifier keys ('escape keys') pressed down,
|
|
then subsequent keystrokes are interpreted as local special actions
|
|
instead of being sent to the remote VNC server.
|
|
|
|
This enables quick parameter changing and also panning of the viewport.
|
|
E.g. the keystroke 'r' is mapped to refresh the screen.
|
|
|
|
Enter 'default' in the entry box to enable this feature and to use the
|
|
default modifier list (Alt_L,Super_L on unix and Control_L,Meta_L on
|
|
macosx) or set it to a list of modifier keys, e.g. Alt_L,Control_L.
|
|
Note that _L means left side of keyboard and _R means right side.
|
|
|
|
Alt_L is the 'Alt' key on the left side of the keyboard, and Super_L
|
|
is usually the 'WindowsFlaggie(TM)' on the left side of the keyboard,
|
|
so when both of those are pressed, the escape keys mapping take effect.
|
|
|
|
|
|
Here is info from the ssvncviewer(1) manual page:
|
|
|
|
-escape str This sets the 'Escape Keys' modifier sequence and enables
|
|
escape keys mode. When the modifier keys escape sequence
|
|
is held down, the next keystroke is interpreted locally
|
|
to perform a special action instead of being sent to the
|
|
remote VNC server.
|
|
|
|
Use '-escape default' for the default modifier sequence.
|
|
(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
|
|
|
|
Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu:
|
|
|
|
Escape Keys: Enter a comma separated list of modifier keys to be the
|
|
'escape sequence'. When these keys are held down, the next keystroke is
|
|
interpreted locally to invoke a special action instead of being sent to
|
|
the remote VNC server. In other words, a set of 'Hot Keys'.
|
|
|
|
To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.
|
|
|
|
Here is the list of hot-key mappings to special actions:
|
|
|
|
r: refresh desktop b: toggle bell c: toggle full-color
|
|
f: file transfer x: x11cursor z: toggle Tight/ZRLE
|
|
l: full screen g: graball e: escape keys dialog
|
|
s: scale dialog +: scale up (=) -: scale down (_)
|
|
t: text chat a: alphablend cursor
|
|
V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n
|
|
|
|
Arrow keys: pan the viewport about 10% for each keypress.
|
|
PageUp / PageDown: pan the viewport by a screenful vertically.
|
|
Home / End: pan the viewport by a screenful horizontally.
|
|
KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.
|
|
Dragging the Mouse with Button1 pressed also pans the viewport.
|
|
Clicking Mouse Button3 brings up the Popup Menu.
|
|
|
|
The above mappings are *always* active in ViewOnly mode, unless you set the
|
|
Escape Keys value to 'never'.
|
|
|
|
If the Escape Keys value below is set to 'default' then a default list of
|
|
of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it
|
|
is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag
|
|
on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side
|
|
of the keyboard.
|
|
|
|
On Unix the default is Alt and Windows keys on Left side of keyboard.
|
|
On MacOSX the default is Control and Command keys on Left side of keyboard.
|
|
|
|
Example: Press and hold the Alt and Windows keys on the LEFT side of the
|
|
keyboard and then press 'c' to toggle the full-color state. Or press 't'
|
|
to toggle the ultravnc Text Chat window, etc.
|
|
|
|
To use something besides the default, supply a comma separated list (or a
|
|
single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
|
|
Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
|
|
}
|
|
|
|
.ekh.f.t insert end $msg
|
|
jiggle_text .ekh.f.t
|
|
}
|
|
|
|
# Or Alternatively one can supply both hosts separated by
|
|
# spaces (with the proxy second) in the VNC Host:Display box:
|
|
#
|
|
# VNC Host-Display: far-away.east:0 theproxy.net:8080
|
|
#
|
|
# This looks a little strange, but it actually how SSVNC stores the
|
|
# host info internally.
|
|
|
|
# You can also specify the remote SSH command by putting a string like
|
|
#
|
|
# cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost
|
|
#
|
|
# (use any command you wish to run) at the END of the VNC Host:Display
|
|
# entry. In general, you can cram it all in the VNC Host:Display if
|
|
# you like: host:disp proxy:port cmd=... (this is the way it is
|
|
# stored internally).
|
|
|
|
proc help_certs {} {
|
|
toplev .ch
|
|
|
|
set h 33
|
|
if [small_height] {
|
|
set h 28
|
|
}
|
|
scroll_text_dismiss .ch.f 87 $h
|
|
|
|
center_win .ch
|
|
wm resizable .ch 1 0
|
|
|
|
wm title .ch "SSL Certificates Help"
|
|
|
|
set msg {
|
|
Description:
|
|
|
|
*** IMPORTANT ***: Only with SSL Certificate verification (either manually
|
|
or via a Certificate Authority certificate) can Man-In-The-Middle attacks be
|
|
prevented. Otherwise, only passive network sniffing attacks are prevented.
|
|
There are hacker tools like dsniff/webmitm and cain that implement SSL
|
|
Man-In-The-Middle attacks. They rely on the client user not bothering to
|
|
check the cert.
|
|
|
|
Some people may be confused by the above because they are familiar with
|
|
their Web Browser using SSL (i.e. https://... websites) and those sites
|
|
are authenticated securely without the user's need to verify anything
|
|
manually. The reason why this happens automatically is because 1) their
|
|
web browser comes with a bundle of Certificate Authority certificates
|
|
and 2) the https sites have paid money to the Certificate Authorities to
|
|
have their website certificate signed by them. When using SSL in VNC we
|
|
normally do not do something this sophisticated, and so we have to verify
|
|
the certificates manually. However, it is possible to use Certificate
|
|
Authorities with SSVNC; that method is described below.
|
|
|
|
The SSL Certificate files described below may have been created externally
|
|
(e.g. by x11vnc or openssl): you can import them via "Import Certificate".
|
|
OR you can click on "Create Certificate ..." to use THIS program to generate
|
|
a Certificate + Private Key pair for you (in this case you will need to
|
|
distribute one of the generated files to the VNC Server).
|
|
|
|
Then you associate the Saved cert with the VNC server, see the panel entry
|
|
box description below. Then click Connect. You will usually want to Save
|
|
this association in a VNC Server profile for the next time you connect.
|
|
|
|
Expiration:
|
|
|
|
SSL Certificates will Expire after a certain period (usually 1-2 years;
|
|
if you create a cert with this tool you can set it to any length you want).
|
|
So if for a particular Cert you find you can no longer connect, check the
|
|
STUNNEL log output to see if the cert has expired. Then create and distribute
|
|
a new one.
|
|
|
|
Fetch Cert:
|
|
|
|
You can also retrieve and view the VNC Server's Cert via the "Fetch Cert"
|
|
button on the main panel. After you check that it is the correct Cert (e.g. by
|
|
comparing MD5 hash or other info), you can save it. The file it was saved
|
|
as will be set as the "ServerCert" to verify against for the next connection.
|
|
To make this verification check permanent, you will need to save the profile
|
|
via 'Save'.
|
|
|
|
NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" WILL NOT
|
|
WORK when a Certificate Authority (CA) is used (i.e. you need to save the CA's
|
|
cert instead.) It will work if the certificate is Self-Signed.
|
|
|
|
Verify All Certs:
|
|
|
|
If "Verify All Certs" is checked on the main panel, you are always forced
|
|
to check unrecognized server certs, and so the first time you connect to
|
|
a new server you may need to follow a few dialogs to inspect and save the
|
|
server certificate.
|
|
|
|
Under "Verify All Certs", new certificates are saved in the 'Accepted Certs'
|
|
directory. When the checkbox is set all host profiles with "CertsDir" set to
|
|
"ACCEPTED_CERTS" (and an empty "ServerCert" setting) will be checked against
|
|
the pool of accepted certificates in the 'Accepted Certs' directory.
|
|
|
|
Note that we have "Verify All Certs" on by default so that users who do not
|
|
understand the SSL Man-In-The-Middle problem will not be left completely
|
|
vulnerable to it. Everyone still must make the effort to verify new
|
|
certificates by an external method to be completely safe.
|
|
|
|
To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or set
|
|
SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to see the
|
|
button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1.
|
|
|
|
Note: "Fetch Cert" and "Verify All Certs" are currently not implemented in
|
|
"SSH + SSL" mode. In this case to have server authentication "ServerCert"
|
|
must be set explicitly to a file (or "CertsDir" to a directory).
|
|
|
|
Also note that "Fetch Cert" only works in a limited fashion in "Listen"
|
|
mode (it is the VNC Server that initiates the connection), and so you
|
|
may need to be set via "ServerCert" as well.
|
|
|
|
NOTE: See the CA section below for how "Fetch Cert/Verify All Certs"
|
|
WILL NOT WORK when a Certificate Authority (CA) is used (i.e. you need
|
|
to save the CA's cert instead.) The "Fetch Cert" saving method will
|
|
work if the certificate is Self-Signed.
|
|
|
|
CA:
|
|
|
|
One can make SSL VNC server authentication more "automatic" as it is in
|
|
Web Browsers going to HTTPS sites, by using a Certificate Authority (CA)
|
|
cert (e.g. a professional one like Verisign or Thawte, or one your company
|
|
or organization creates) for the "ServerCert". This is described in detail
|
|
here: http://www.karlrunge.com/x11vnc/ssl.html
|
|
|
|
CA's are not often used, but if the number of VNC Servers scales up it can
|
|
be very convenient because the viewers (i.e. SSVNC) only need the CA cert,
|
|
not all of the Server certs.
|
|
|
|
IMPORTANT NOTE: if a VNC Server is using a CA signed certificate instead
|
|
of its own Self-Signed one, then "Fetch Cert", etc. saving mechanism
|
|
WILL NOT WORK. You must obtain the CA certificate and explicitly set
|
|
it as the ServerCert or import it to 'Accepted Certs'.
|
|
|
|
|
|
Now what goes into the panel's entry boxes is described.
|
|
|
|
|
|
Your Certificate + Key (MyCert):
|
|
|
|
You can specify YOUR own SSL certificate (PEM) file in "MyCert" in which
|
|
case it is used to authenticate YOU (the viewer) to the remote VNC Server.
|
|
If this fails the remote VNC Server will drop the connection.
|
|
|
|
So the Server could use this method to authenticate Viewers instead of the
|
|
more common practice of using a VNC password or x11vnc's -unixpw mode.
|
|
|
|
|
|
Server Certificates (ServerCert/CertsDir):
|
|
|
|
Server certs can be specified in one of two ways:
|
|
|
|
- A single certificate (PEM) file for a single server
|
|
or a single Certificate Authority (CA)
|
|
|
|
- A directory of certificate (PEM) files stored in
|
|
the special OpenSSL hash fashion.
|
|
|
|
The former is set via "ServerCert" in this gui.
|
|
The latter is set via "CertsDir" in this gui.
|
|
|
|
The former corresponds to the "CAfile" STUNNEL parameter.
|
|
The latter corresponds to the "CApath" STUNNEL parameter.
|
|
|
|
See stunnel(8) or stunnel.mirt.net for more information.
|
|
|
|
If the remote VNC Server fails to authenticate itself with respect to the
|
|
specified certificate(s), then the VNC Viewer (your side) will drop the
|
|
connection.
|
|
|
|
Select which file or directory by clicking on the appropriate "Browse..."
|
|
button. Once selected, if you click Info or the Right Mouse button on
|
|
"Browse..." then information about the certificate will be displayed.
|
|
|
|
If, as is the default, "CertsDir" is set to the token "ACCEPTED_CERTS"
|
|
(and "ServerCert" is unset) then the certificates accumulated in the special
|
|
'Accepted Certs' directory will be used. "ACCEPTED_CERTS" is the default for
|
|
every server ("Verify All Certs"). Note that if you ever need to clean this
|
|
directory, each cert is saved in two files, for example:
|
|
|
|
hostname-0=bf-d0-d6-9c-68-5a-fe-24-c6-60-ba-b4-14-e6-66-14.crt
|
|
and
|
|
9eb7c8be.0
|
|
|
|
This is because of the way OpenSSL must use hash-based filenames in Cert dirs.
|
|
The file will have a "full filename:" line indicating the fingerprint and
|
|
hostname associated with it. Be sure to remove both files. The Delete Certs
|
|
dialog should automatically find the matching one for you and prompt you to
|
|
remove it as well.
|
|
|
|
Certificate Revocation List (CRL File):
|
|
|
|
For large scale deployments, usually involving a CA Cert, it is worthwhile
|
|
to be able to revoke individual certs (so that a new CA cert does not need to
|
|
be created and new keys distributed). Set CRL File to the path to the
|
|
file containing the revoked certificates (or a directory containing
|
|
OpenSSL style hash-based filenames.) See the x11vnc -sslCRL documentation
|
|
for how to create CRL's. In short, the commands 'openssl ca -revoke ...'
|
|
and 'openssl ca -gencrl ...' are the ones to look for; See the ca(1) manpage.
|
|
|
|
Create Certificate:
|
|
|
|
A simple dialog to create a Self-Signed Certificate. See the x11vnc
|
|
-sslGenCA, -sslGenCert options for creating a CA Cert and signing with it.
|
|
|
|
Import Certificate:
|
|
|
|
You can paste in a Certificate or read one in from a file to add to your
|
|
list of Server Certificates. If (also) saved in the 'Accepted Certs'
|
|
directory, it will be automatically used to verify any Server when in
|
|
'Verify All Certs' Mode.
|
|
|
|
Deleting Certificates:
|
|
|
|
To delete a Certificate+private_key pair click on "Delete Certificate"
|
|
and select one in the menu. You will be prompted to remove it,
|
|
and also any corresponding .pem or .crt file. For "ACCEPTED_CERTS"
|
|
it will find the matching "HASH" file and prompt you to remove that too.
|
|
|
|
|
|
Default Certs and Keys:
|
|
|
|
Use the "-mycert file" option (same as "-cert file") to set a default
|
|
MyCert. The user will then have to manually clear the field to not
|
|
use a certificate. This is the same as "mycert=file" (also "cert=file")
|
|
in the ~/.ssvncrc file. If "file" does not exist, then ~/.vnc/certs is
|
|
prepended to it.
|
|
|
|
Use the "-cacert file" option (same as "-ca file") to set a default
|
|
ServerCert. The user will then have to manually clear the field to not
|
|
set a server cert. This is the same as "cacert=file" (also "ca=file")
|
|
in the ~/.ssvncrc file. If "file" does not exist, then ~/.vnc/certs is
|
|
prepended to it. Use "-cacert CA" to set it to ~/.vnc/certs/CA/cacert.pem
|
|
|
|
Use the "-crl file" option to set a default CRL File. The user will
|
|
then have to manually clear the field to not use a CRL. This is the
|
|
same as "crl=file" in the ~/.ssvncrc file. If "file" does not exist,
|
|
then ~/.vnc/certs is prepended to it.
|
|
|
|
A sys-admin might set up an SSVNC deployment for user's workstations or
|
|
laptops using one or more of -cacert (authenticate VNC server to the
|
|
user) or -mycert (authenticate user to VNC server) or -crl (supply a
|
|
list of revoked certificates). Prefix either one with "FORCE:" to make
|
|
the setting unchangable.
|
|
|
|
|
|
Notes:
|
|
|
|
If "Use SSH" has been selected then SSL certs are disabled.
|
|
|
|
See the x11vnc and STUNNEL documentation for how to create and use PEM
|
|
certificate files:
|
|
|
|
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
|
|
http://www.karlrunge.com/x11vnc/ssl.html
|
|
http://stunnel.mirt.net
|
|
|
|
A common way to create and use a VNC Server certificate is:
|
|
|
|
x11vnc -ssl SAVE ...
|
|
|
|
and then copy the Server certificate to the local (viewer-side) machine.
|
|
x11vnc prints out to the screen the Server certificate it generates
|
|
(stored in ~/.vnc/certs/server.crt). You can set "ServerCert" to it
|
|
directly or use the "Import Certificate" action to save it to a file.
|
|
Or use the "Fetch Cert" method to retrieve it (be sure to verify the
|
|
MD5 fingerprint, etc).
|
|
|
|
x11vnc also has command line utilities to create server, client, and CA
|
|
(Certificate Authority) certificates and sign with it. See the above URLs.
|
|
}
|
|
|
|
.ch.f.t insert end $msg
|
|
jiggle_text .ch.f.t
|
|
}
|
|
|
|
proc help_ts_opts {} {
|
|
toplev .oh
|
|
|
|
scroll_text_dismiss .oh.f
|
|
|
|
center_win .oh
|
|
|
|
wm title .oh "Terminal Services VNC Options Help"
|
|
|
|
set msg {
|
|
Options: Click on a checkbox to enable a feature and bring up its Dialog.
|
|
Deselecting a checkbox will disable the feature (but settings from the
|
|
Dialog are remembered). Click on it again to re-enable.
|
|
|
|
|
|
Desktop Type:
|
|
|
|
The default type of remote Desktop type is the "kde" (The K Desktop
|
|
Environment) You can choose a different type: gnome, failsafe,
|
|
twm, etc.
|
|
|
|
This setting will ONLY be used if the desktop needs to be created.
|
|
If an existing session of yours is found it will be used instead
|
|
(log out of that session if you want to create a new Desktop type
|
|
or see the Multiple Sessions option under Advanced).
|
|
|
|
Desktop Size:
|
|
|
|
The default size of remote Desktop type is the "1280x1024" with a
|
|
Color depth of 16 bits per pixel (BPP). Choose one of the standard
|
|
WxH values or enter a custom one (TBD).
|
|
|
|
This setting will ONLY be used if the desktop needs to be created.
|
|
If an existing session of yours is found it will be used instead
|
|
(log out of that session if you want to create a new Desktop size
|
|
or see the Multiple Sessions option under Advanced).
|
|
|
|
Some X servers, Xdummy or a real X server, will allow dynamic screen
|
|
size changing after the session has started via a GUI configuration
|
|
tool (or xrandr(1) from the command line).
|
|
|
|
X Server Type:
|
|
|
|
The default type of remote X session is the "Xvfb" (X virtual frame
|
|
buffer) X server. It is available on most systems. To choose a
|
|
different type, select "Xdummy", "Xvnc", "Xvnc.redirect".
|
|
|
|
Xdummy is part of the x11vnc project and is a virtual X server with
|
|
some nice features, but it Linux only and requires root permission
|
|
to run. One user put 'ALL ALL = NOPASSWD: /usr/local/bin/Xdummy*'
|
|
in his sudo(1) configuration (via visudo).
|
|
|
|
For Xvnc that server is started up, and x11vnc polls it in its
|
|
normal way. Use Xvnc.redirect if you want x11vnc to find and/or
|
|
create the Xvnc session, but after that merely transfer packets back
|
|
and forth between VNC viewer and Xvnc (I.e. x11vnc does no polling
|
|
or VNC protocol).
|
|
|
|
|
|
Enable Printing:
|
|
|
|
This sets up a SSH port redirection for you from your remote session
|
|
to your local print server. The CUPS mechanism is used. The local
|
|
print server can also be SMB/Windows.
|
|
|
|
Enable Sound:
|
|
|
|
Not completely implemented yet. A partially working ESD method
|
|
is provided. It may change over to http://nas.sourceforge.net in
|
|
the future. As with printing, it uses a SSH port redirection to a
|
|
server running locally.
|
|
|
|
File Transfer:
|
|
|
|
x11vnc supports both the UltraVNC and TightVNC file transfer
|
|
extensions. On Windows both viewers support their file transfer
|
|
protocol. On Unix only the SSVNC VNC Viewer has filexfer support;
|
|
it supports the UltraVNC flavor via a Java helper program.
|
|
|
|
Choose the one you want based on VNC viewer you will use.
|
|
The defaults for the SSVNC viewer package are TightVNC on Windows
|
|
and UltraVNC on Unix.
|
|
|
|
View Only:
|
|
|
|
Start the VNC Viewer in View-Only mode (it may be switched to full
|
|
access later in the session).
|
|
|
|
Change VNC Viewer:
|
|
|
|
If you do not like the VNC Viewer bundled in the package, you can
|
|
indicate another one here.
|
|
|
|
X11 viewer MacOSX:
|
|
|
|
On MacOSX try to use the bundled X11 vncviewer instead of the
|
|
Chicken of the VNC viewer; the Xquartz X server must be installed
|
|
(it is by default on 10.5.x) and the DISPLAY variable must be set
|
|
(see Tip 15 of SSVNC Help to do this manually.)
|
|
|
|
|
|
Advanced Options:
|
|
|
|
VNC Shared:
|
|
|
|
Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous
|
|
shared access of the remote desktop: You simply log in as many
|
|
times from as many different locations with 'tsvnc' as you like.
|
|
|
|
Select this option for the traditional VNC server shared mode of
|
|
operation using a single x11vnc server. SSH access is still required.
|
|
|
|
Multiple Sessions:
|
|
|
|
To enable one user to have more than one Terminal Services Desktop
|
|
X session on a single machine, this option lets you create Tags for
|
|
multiple ones (e.g. KDE_BIG, TWM_800x600)
|
|
|
|
X Login Greeter:
|
|
|
|
If you have root (sudo(1)) permission on the remote machine,
|
|
you can have x11vnc try to connect to X displays that have nobody
|
|
logged in yet. This is most likely the login greeter running on
|
|
the Physical console. sudo(1) is used to run x11vnc with FD_XDM=1.
|
|
|
|
An initial ssh running 'sudo id' is performed to try to 'prime'
|
|
sudo so the 2nd one that starts x11vnc does not need a password.
|
|
|
|
Note that if someone is already logged into the console of the XDM
|
|
display you will see their X session.
|
|
|
|
Other VNC Server:
|
|
|
|
The x11vnc program running on the remote machine can be instructed to
|
|
immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so)
|
|
VNC server.
|
|
|
|
Use unixpw:
|
|
|
|
This enables the x11vnc unixpw mode. A Login: and Password: dialog
|
|
will be presented in the VNC Viewer for the user to provide any Unix
|
|
username and password whose session he wants to connect to.
|
|
|
|
This mode is useful if a shared terminal services user (e.g. 'tsuser')
|
|
is used for the SSH login part (say via the SSH authorized_keys
|
|
mechanism and all users share the same private SSH key for 'tsuser').
|
|
|
|
In normal usage the per-user SSH login should be the simplest and
|
|
sufficient, in which case the unixpw option should NOT be selected.
|
|
|
|
Client 8bit Color:
|
|
|
|
Have the VNC Viewer request low color mode (8 bits per pixel) for
|
|
slow links. This may be disabled or further tuned (e.g. 64 color
|
|
mode) in the viewer during the session.
|
|
|
|
Client-Side Caching:
|
|
|
|
x11vnc has an experiment Client-Side caching scheme "-ncache n"
|
|
that can give nice speedups. But there are some drawbacks
|
|
because the cache-region is visible and uses much RAM.
|
|
http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
|
|
|
|
X11VNC Options:
|
|
|
|
If you are familiar with x11vnc, you can specify any of its features
|
|
that you would like enabled.
|
|
|
|
SSVNC Mode:
|
|
|
|
Clicking on this button will return you to the full SSVNC Mode.
|
|
|
|
Unix ssvncviewer:
|
|
|
|
Clicking on this button will popup a menu for setting options
|
|
of the Unix (and Mac OS X) provided SSVNC vncviewer.
|
|
|
|
|
|
~/.ssvncrc file:
|
|
|
|
You can put global options in your ~/.ssvncrc file (ssvnc_rc on
|
|
Windows). Currently they are:
|
|
|
|
Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
|
|
the application start up in the given mode.
|
|
|
|
desktop_type=wmaker (e.g.) to switch the default Desktop Type.
|
|
|
|
desktop_size=1280x1024 (e.g.) to switch the default Desktop Size.
|
|
|
|
desktop_depth=24 (e.g.) to switch the default Desktop Color Depth.
|
|
|
|
xserver_type=Xdummy (e.g.) to switch the default X Server Type.
|
|
|
|
(The above 4 settings apply only to the Terminal Services Mode.)
|
|
|
|
noenc=1 (same as the -noenc option for a 'No Encryption' option)
|
|
noenc=0 (do not show the 'No Encryption' option)
|
|
|
|
font_default=tk-font-name (sets the font for menus and buttons)
|
|
font_fixed=tk-font-name (sets the font for help text)
|
|
}
|
|
.oh.f.t insert end $msg
|
|
jiggle_text .oh.f.t
|
|
}
|
|
|
|
proc help_opts {} {
|
|
toplev .oh
|
|
|
|
scroll_text_dismiss .oh.f
|
|
|
|
center_win .oh
|
|
|
|
wm title .oh "SSL/SSH Viewer Options Help"
|
|
|
|
set msg {
|
|
Use SSL: The default, use SSL via STUNNEL (this requires SSL aware VNC
|
|
server, e.g. x11vnc -ssl SAVE ...) See the description in the
|
|
main Help panel.
|
|
|
|
Use SSH: Instead of using STUNNEL SSL, use ssh(1) for the encrypted
|
|
tunnel. You must be able to log in via ssh to the remote host.
|
|
|
|
On Unix the cmdline ssh(1) program (it must already be installed)
|
|
will be run in an xterm for passphrase authentication, prompts
|
|
about RSA keys, etc. On Windows the cmdline plink.exe program
|
|
will be launched in a Windows Console window. (Apologies for
|
|
the klunkiness..)
|
|
|
|
You can set the "VNC Host:Display" to "user@host:disp" to
|
|
indicate ssh should log in as "user" on "host". NOTE: On
|
|
Windows you *MUST* always supply the "user@" part (due to a
|
|
plink deficiency). E.g.:
|
|
|
|
VNC Host:Display: fred@far-away.east:0
|
|
|
|
|
|
Gateway: If an intermediate gateway machine must be used
|
|
(e.g. to enter a firewall; the VNC Server is not running on it),
|
|
put it in the Proxy/Gateway entry, e.g.:
|
|
|
|
VNC Host:Display: workstation:0
|
|
Proxy/Gateway: user@gateway-host:port
|
|
|
|
ssh is used to login to user@gateway-host and then a -L port
|
|
redirection is set up to go to workstation:0 from gateway-host.
|
|
":port" is optional, use it if the gateway-host SSH port is
|
|
not the default value 22.
|
|
|
|
Chaining 2 ssh's: One can also do a "double ssh", i.e. a
|
|
first SSH to the gateway login machine then a 2nd ssh to the
|
|
destination machine (presumably it is running the vnc server).
|
|
|
|
Unlike the above example, the "last leg" (gateway-host ->
|
|
workstation) is also encrypted by SSH this way. Do this by
|
|
splitting the gateway in two with a comma, the part before it
|
|
is the first SSH:
|
|
|
|
VNC Host:Display: localhost:0
|
|
Proxy/Gateway: user@gateway-host:port,user@workstation:port
|
|
|
|
Web and SOCKS proxies can also be used with SSH:
|
|
|
|
VNC Host:Display: user@workstation:0
|
|
Proxy/Gateway: socks://socks.server:1080
|
|
|
|
See the "SSH Proxies/Gateways" in the Main Help document for full
|
|
details.
|
|
|
|
|
|
Remote Command: In the "Remote SSH Command" entry you can to
|
|
indicate that a remote command to be run. The default is
|
|
"sleep 15" to make sure port redirections get established. But you
|
|
can run anything else, for example, to run x11vnc on your X :0
|
|
workstation display:
|
|
|
|
x11vnc -display :0 -nopw
|
|
|
|
|
|
Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN
|
|
SSHD server) there may be no "sleep" command so put in something
|
|
like "ping localhost" or "ping -n 10 -w 1000 localhost" to
|
|
set a short delay to let the port redir get established.
|
|
|
|
|
|
Trick: If you use "SHELL" asl the "Remote SSH Command" then
|
|
you get an SSH shell only: no VNC viewer will be launched.
|
|
On Windows "PUTTY" will try to use putty.exe (better terminal
|
|
emulation than plink.exe) A shortcut for this is Ctrl-S as
|
|
long as user@hostname is present in the "VNC Host:Display" box.
|
|
|
|
|
|
Use SSH + SSL:
|
|
|
|
Tunnel the SSL connection through a SSH tunnel. Use this
|
|
if you want end-to-end SSL and must use a SSH gateway (e.g. to
|
|
enter a firewall) or if additional SSH port redirs are required
|
|
(CUPS, Sound, SMB tunnelling: See Advanced Options).
|
|
|
|
This is a RARELY used mode, but included in case the need arises.
|
|
|
|
|
|
No Encryption:
|
|
|
|
In '-noenc' mode, which is now the default, (Ctrl-E also toggles
|
|
this mode), use this to make a Direct connection to the VNC Server
|
|
with no encryption whatsoever. (Be careful about passwords, etc.)
|
|
|
|
The -noenc mode is now the default since SSVNC 1.0.25, use
|
|
the '-enc' cmdline option to disable the button.
|
|
|
|
|
|
Automatically Find X Session:
|
|
|
|
When using SSH mode to connect, you can select this option. It
|
|
simply sets the Remote SSH Command to:
|
|
|
|
PORT= x11vnc -find -localhost
|
|
|
|
This requires that x11vnc is installed on the remote computer
|
|
and is available in $PATH for the ssh login. The command
|
|
"x11vnc -find -localhost" command is run on the remote
|
|
machine.
|
|
|
|
The -find option causes x11vnc to try to find an existing X
|
|
session owned by the user (i.e. who you ssh in as). If it
|
|
does it attaches to it; otherwise the x11vnc VNC server exits
|
|
immediately followed by your VNC Viewer.
|
|
|
|
The PORT= option just means to let x11vnc pick its own
|
|
VNC port and then connect to whatever it picked. Use P=
|
|
for more debugging output.
|
|
|
|
The idea for this mode is you simply type 'username@workstation'
|
|
in the VNC Host:Display box, Select 'Options -> Automatically
|
|
Find X Session', and then click Connect. The tsvnc mode is
|
|
similar (it runs x11vnc on the remote side with the intent
|
|
of automatically finding, or creating, your desktop).
|
|
|
|
|
|
Unix Username & Password:
|
|
|
|
This is only available on Unix and MacOSX and when using
|
|
the SSVNC enhanced TightVNC viewer (it has been modified to
|
|
do Unix logins). It supports a login dialog with servers
|
|
doing something like x11vnc's "-unixpw" mode. After any
|
|
regular VNC authentication takes place (VNC Password), then
|
|
it sends the Unix Username, a Return, the Unix Password and
|
|
a final Return. This saves you from typing them into the
|
|
"login:" and "Password:" prompts in the viewer window.
|
|
|
|
Note that the x11vnc -unixpw login mode is external to the
|
|
VNC protocol, so you need to be sure the VNC server is in
|
|
this mode and will be waiting for the dialog. Otherwise the
|
|
username and password will be typed directly into the desktop
|
|
application that happens to have the focus!
|
|
|
|
When you select this option "Unix Username:" and "Unix
|
|
Password:" entry boxes appear on the main panel where you can
|
|
type them in. x11vnc has settings that can be specified after
|
|
a ":" in the Unix username; they may be used here as well.
|
|
(For example: username:3/4,nc for a smaller screen and -nocache)
|
|
|
|
If the Unix Username is not set when you click Connect, then
|
|
any SSH username@host is used. Otherwise the environment
|
|
variable $USER or $LOGNAME and finally whoami(1) is used.
|
|
|
|
Also Note that the Unix Password is never saved in a VNC
|
|
profile (so you have to type it each time). Also, the remote
|
|
x11vnc server is instructed to not echo the Username string
|
|
by sending an initial Escape. Set the SSVNC_UNIXPW_NOESC=1
|
|
environment variable to override this.
|
|
|
|
Reverse VNC Connection:
|
|
|
|
Reverse (listening) VNC connections are possible as well.
|
|
Enable with this button "Reverse VNC Connection (-LISTEN)"
|
|
|
|
In this case the VNC Server initiates the connection to your
|
|
waiting (i.e. listening) SSVNC viewer.
|
|
|
|
For SSL connections in the 'VNC Host:Display' entry box put in
|
|
the number (e.g. "0" or ":0" or ":1", etc.) that corresponds to
|
|
the Listening display (0 -> port 5500, 1 -> port 5501, etc.) you
|
|
want to use. For example x11vnc can then be used via:
|
|
"x11vnc ... -ssl SAVE -connect hostname:port" using the "port"
|
|
with the one you chose.
|
|
|
|
Clicking on the 'Listen' button puts your SSVNC viewer
|
|
in a "listening" state on that port number, waiting for a
|
|
connection from the VNC Server.
|
|
|
|
Then a VNC server should establish a reverse connection to
|
|
that port on this machine (e.g. -connect this-machine:5500
|
|
or -connect this-machine:5503, etc.)
|
|
|
|
Server SSL certificates will be verified, however you WILL
|
|
NOT be prompted about unrecognized ones; rather, you MUST
|
|
set up the correct Server certificate (e.g. by importing).
|
|
prior to any connections.
|
|
|
|
If the connection is failing in Reverse VNC (listening) mode,
|
|
check the STUNNEL log output to see if STUNNEL is unable to
|
|
authenticate the VNC Server. If you want to allow in a
|
|
reverse connection with NO Server authentication, unset the
|
|
'Verify All Certs' option.
|
|
|
|
When listening in SSL, you will ALSO need to specify YOUR
|
|
OWN SSL cert, "MyCert", or otherwise let the GUI prompt you
|
|
to create a "listen.pem" and use that.
|
|
|
|
The "listen.pem" will be reused in later SSL Listening
|
|
connections unless you specify a different one with MyCert.
|
|
|
|
On Windows or using a 3rd party VNC Viewer multiple,
|
|
simultaneous reverse connections are always enabled.
|
|
On Unix/MacOSX with the provided ssvncviewer they are disabled
|
|
by default. To enable them:
|
|
Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Conns.
|
|
|
|
For reverse connections in SSH or SSH + SSL modes it is a
|
|
little trickier. The SSH tunnel (with -R tunnel) must be
|
|
established and remain up waiting for reverse connections.
|
|
The default time is "sleep 1800", i.e. 30 mins. You can put
|
|
a longer or shorter sleep in "Remote SSH Command" (perhaps
|
|
after your command runs: cmd; sleep 3600).
|
|
|
|
For SSH reverse connections put "hostname:n" in
|
|
'VNC Host:Display' or "user@hostname:n". The "n" will be the
|
|
listening display on the *REMOTE* side. So to have the remote
|
|
x11vnc connect use: "x11vnc ... -connect localhost:n" or
|
|
"x11vnc -R connect:localhost:n" (-ssl will be needed for SSH+SSL
|
|
mode). If the -R port cannot be opened because it is in use
|
|
by another program you will have to kill everything and start
|
|
over using a different port.
|
|
|
|
In reverse connections mode be careful to protect the listening
|
|
VNC Viewer from direct connections (neither SSL nor SSH)
|
|
connecting directly to its listening port thereby bypassing
|
|
the tunnel. This can be done by a host-level firewall that
|
|
only lets in, say, port 5500 (the default one ":0" for stunnel
|
|
to listen on). Or for SSH reverse connections allow NO 5500+n
|
|
ports in. For reverse connections, the Unix enhanced tightvnc
|
|
viewers supplied in the SSVNC package will only listen on
|
|
localhost so these precautions are not needed.
|
|
|
|
Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
|
|
only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0
|
|
Also works for UN-encrypted reverse connections as well ('None').
|
|
|
|
Note that for SSL connections use of "Proxy/Gateway" does not
|
|
make sense: the remote side cannot initiate its reverse connection
|
|
via the Proxy.
|
|
|
|
Note that for SSH or SSH+SSL connections use of "Proxy/Gateway"
|
|
does not make sense (the ssh cannot do a -R on a remote host:port),
|
|
unless it is a double proxy where the 2nd host is the machine with
|
|
the VNC server.
|
|
|
|
|
|
View Only: Have VNC Viewer ignore mouse and keyboard input.
|
|
|
|
Fullscreen: Start the VNC Viewer in fullscreen mode.
|
|
|
|
Raise On Beep: Deiconify viewer when bell rings.
|
|
|
|
Use 8bit color: Request a very low-color pixel format.
|
|
|
|
Do not use JPEG: Do not use the jpeg aspect of the tight encoding.
|
|
|
|
Use X11 vncviewer on MacOSX:
|
|
On MacOSX try to use the bundled X11 vncviewer
|
|
instead of the Chicken of the VNC viewer;
|
|
The Xquartz X server must be installed (it is by
|
|
default on 10.5.x) and the DISPLAY variable must
|
|
be set (see Tip 15 of Help to do this manually.)
|
|
Put cotvnc=1 in ~/.ssvncrc to switch the default.
|
|
|
|
Kill Stunnel Automatically:
|
|
On Windows, automatically try to kill the STUNNEL
|
|
process when the VNC Viewer exits. This is a
|
|
global setting (not per-profile); it can be also
|
|
set via either the -killstunnel cmdline option,
|
|
or killstunnel=1 in ssvnc_rc. To disable it supply
|
|
-nokillstunnel or put killstunnel=0 in ssvnc_rc.
|
|
As of 1/2009 this option is on by default.
|
|
|
|
The main drawback to having STUNNEL automatically
|
|
killed is that you will not be able to view its
|
|
logfile. If you are having trouble connecting via
|
|
SSL, disable this option and double click on the
|
|
dark green STUNNEL icon in the tray to view the log.
|
|
|
|
|
|
Compress Level/Quality: Set TightVNC encoding parameters.
|
|
|
|
|
|
Putty PW: On Windows only: use the supplied password for plink SSH
|
|
logins. Unlike the other options the value is not saved
|
|
when 'Save' is performed. This feature is useful when
|
|
options under "Advanced" are set that require TWO SSH's:
|
|
you just have to type the password once in this entry box.
|
|
The bundled pageant.exe and puttygen.exe programs can also
|
|
be used to avoid repeatedly entering passwords (note this
|
|
requires setting up and distributing SSH keys). Start up
|
|
pageant.exe or puttygen.exe and read the instructions there.
|
|
|
|
Note, that there is a small exposure to someone seeing the
|
|
putty password on the plink command line.
|
|
|
|
Note that the Putty PW is not cleared if you load in a
|
|
new VNC profile.
|
|
|
|
|
|
Port Slot: On Windows ports cannot be selected or checked as easily as
|
|
on Unix. So listening ports for ssh redirs, proxy tunnelling,
|
|
and etc. things are picked via finding a free "slot".
|
|
The slots run from 30 to 99 and are locked based on the
|
|
existence of a file with the slot number in it. When the
|
|
connection is about to be made, a free slot is found and used
|
|
to work out some ports (e.g. 5930 for the local VNC port,
|
|
etc.) This way simultaneous SSVNC connections can take place.
|
|
|
|
One drawback of this is that Putty/Plink stores SSH keys based
|
|
on hostname:port, and with a proxy tunnel the hostname is
|
|
"localhost". So the Putty key store may have key collisions
|
|
for the localhost tunnels, and plink will prompt you to
|
|
resolve the conflict WRT a different SSH key being discovered.
|
|
|
|
To work around this to some degree you can select a unique
|
|
Port Slot (in the range 50-99) for a specific host. Then the
|
|
ssh redir port to this host will never change and so the
|
|
Putty localhost:fixed-port key should remain valid.
|
|
|
|
|
|
Mode: To change the GUI Mode, select between the full SSVNC
|
|
(i.e. SSL and SSH), SSHVNC (i.e. SSH-Only), and Terminal
|
|
Services mode (TSVNC; uses x11vnc)
|
|
|
|
Note: You can put "mode=tsvnc" or "mode=sshvnc" in your
|
|
~/.ssvncrc file (ssvnc_rc on Windows) to have the application
|
|
start up in the given mode.
|
|
|
|
|
|
Show 'No Encryption' Option:
|
|
|
|
Note: since SSVNC 1.0.25 the 'No Encryption' Option is
|
|
enabled by default.
|
|
|
|
Select this to display a button that disables both SSL and
|
|
SSH encryption. This is the same as Ctrl+E. This puts
|
|
a check item "None" on the main panel and also a "No
|
|
Encryption" check item in the "Options" panel. If you
|
|
select this item, there will be NO encryption for the VNC
|
|
connection (use cautiously) See Tip 5) under Help for more
|
|
information about disabling encryption.
|
|
|
|
|
|
Buttons:
|
|
|
|
Use Defaults: Set all options to their defaults (i.e. unset).
|
|
|
|
Delete Profile: Delete a saved profile.
|
|
|
|
Advanced: Bring up the Advanced Options dialog.
|
|
|
|
Save and Load:
|
|
|
|
You can Save the current settings by clicking on Save
|
|
(.vnc file) and you can also read in a saved one with Load
|
|
Profile. Use the Browse... button to select the filename
|
|
via the GUI.
|
|
|
|
Pressing Ctrl-L or Clicking the Right mouse button on the
|
|
main GUI will invoke the Load dialog.
|
|
|
|
Note: On Windows since the TightVNC Viewer will save its own
|
|
settings in the Registry, some unexpected behavior is possible
|
|
because the viewer is nearly always directed to the VNC host
|
|
"localhost:30". E.g. if you specify "View Only" in this gui
|
|
once but not next time the Windows VNC Viewer may remember
|
|
the setting. Unfortunately there is not a /noreg option for
|
|
the Viewer.
|
|
}
|
|
.oh.f.t insert end $msg
|
|
jiggle_text .oh.f.t
|
|
}
|
|
|
|
proc help_fetch_cert {{selfsigned 1}} {
|
|
toplev .fh
|
|
|
|
set h 35
|
|
if [small_height] {
|
|
set h 28
|
|
}
|
|
scroll_text_dismiss .fh.f 85 $h
|
|
|
|
center_win .fh
|
|
wm resizable .fh 1 0
|
|
|
|
wm title .fh "Fetch Certificates Help"
|
|
|
|
set msg {
|
|
The displayed SSL Certificate has been retrieved from the VNC Server via the
|
|
"Fetch Cert" action.
|
|
|
|
It has merely been downloaded via the SSL Protocol:
|
|
|
|
*** IT HAS NOT BEEN VERIFIED OR AUTHENTICATED IN ANY WAY ***
|
|
|
|
So, in principle, it could be a fake certificate being inserted by a bad
|
|
person attempting to perform a Man-In-The-Middle attack on your SSL connection.
|
|
|
|
If, however, by some external means you can verify the authenticity of this SSL
|
|
Certificate you can use it for your VNC SSL connection to the VNC server you
|
|
wish to connect to. It will provide an authenticated and encrypted connection.
|
|
|
|
You can verify the SSL Certificate by comparing the MD5 or SHA1 hash value
|
|
via a method/channel you know is safe (i.e. not also under control of a
|
|
Man-In-The-Middle attacker). You could also check the text between the
|
|
-----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags, etc.
|
|
|
|
Once you are sure it is correct, you can press the Save button to save the
|
|
certificate to a file on the local machine for use when you connect via VNC
|
|
tunneled through SSL. If you save it, then that file will be set as the
|
|
Certificate to verify the VNC server against. You can see this in the dialog
|
|
started via the "Certs..." button on the main panel.
|
|
|
|
NOTE: If you want to make Permanent the association of the saved SSL certificate
|
|
file with the VNC server host, you MUST save the setting as a profile for
|
|
loading later. To Save a Profile, click on Options -> Save Profile ...,
|
|
and choose a name for the profile and then click on Save.
|
|
|
|
If "Verify All Certs" is checked, then you are forced to check all new certs.
|
|
In this case the certs are saved in the 'Accepted Certs' directory against
|
|
which all servers will be checked unless "ServerCert" or "CertsDir" has been
|
|
set to something else.
|
|
|
|
To reload the profile at a later time, click on the "Load" button on the
|
|
main panel and then select the name and click "Open". If you want to be
|
|
sure the certificate is still associated with the loaded in host, click on
|
|
"Certs..." button and make sure the "ServerCert" points to the desired SSL
|
|
filename.
|
|
|
|
See the Certs... Help for more information. A sophisticated method can be set
|
|
up using a Certificate Authority key to verify never before seen certificates
|
|
(i.e. like your web browser does).
|
|
}
|
|
|
|
set msg2 {
|
|
--------------------------------------------------------------------------
|
|
NOTE: The certificate that was just downloaded IS NOT a Self-Signed
|
|
certificate. It was signed by a Certificate Authority (CA) instead.
|
|
So saving it does not make sense because it cannot be used to authenticate
|
|
anything.
|
|
|
|
You need to Obtain and Save the CA's certificate instead.
|
|
|
|
The remainder of this Help description applies ONLY to Self-Signed
|
|
certificates (i.e. NOT the most recently downloaded one.)
|
|
--------------------------------------------------------------------------
|
|
|
|
|
|
}
|
|
|
|
if {!$selfsigned} {
|
|
regsub { If, however,} $msg "$msg2 If, however," msg
|
|
}
|
|
|
|
.fh.f.t insert end $msg
|
|
jiggle_text .fh.f.t
|
|
}
|
|
|
|
proc win_nokill_msg {} {
|
|
global help_font is_windows system_button_face
|
|
toplev .w
|
|
|
|
eval text .w.t -width 60 -height 11 $help_font
|
|
button .w.d -text "Dismiss" -command {destroy .w}
|
|
pack .w.t .w.d -side top -fill x
|
|
|
|
apply_bg .w.t
|
|
|
|
center_win .w
|
|
wm resizable .w 1 0
|
|
|
|
wm title .w "SSL/SSH Viewer: Warning"
|
|
|
|
set msg {
|
|
The VNC Viewer has exited.
|
|
|
|
You will need to terminate STUNNEL manually.
|
|
|
|
To do this go to the System Tray and right-click on the STUNNEL
|
|
icon (dark green). Then click "Exit".
|
|
|
|
You can also double click on the STUNNEL icon to view the log
|
|
for error messages and other information.
|
|
}
|
|
.w.t insert end $msg
|
|
}
|
|
|
|
proc win_kill_msg {pids} {
|
|
global terminate_pids
|
|
global help_font
|
|
|
|
toplev .w
|
|
|
|
eval text .w.t -width 72 -height 21 $help_font
|
|
button .w.d -text "Dismiss" -command {destroy .w; set terminate_pids no}
|
|
button .w.k -text "Terminate STUNNEL" -command {destroy .w; set terminate_pids yes}
|
|
pack .w.t .w.k .w.d -side top -fill x
|
|
|
|
apply_bg .w.t
|
|
|
|
center_win .w
|
|
wm resizable .w 1 0
|
|
|
|
wm title .w "SSL/SSH Viewer: Warning"
|
|
|
|
set msg {
|
|
The VNC Viewer has exited.
|
|
|
|
We can terminate the following still running STUNNEL process(es):
|
|
|
|
}
|
|
append msg " $pids\n"
|
|
|
|
append msg {
|
|
Click on the "Terminate STUNNEL" button below to do so.
|
|
|
|
Before terminating STUNNEL you can double click on the STUNNEL
|
|
Tray icon to view its log for error messages and other information.
|
|
|
|
Note: You may STILL need to terminate STUNNEL manually if we are
|
|
unable to kill it. To do this go to the System Tray and right-click
|
|
on the STUNNEL icon (dark green). Then click "Exit". You will
|
|
probably also need to hover the mouse over the STUNNEL Tray Icon to
|
|
make the Tray notice STUNNEL is gone...
|
|
|
|
To have STUNNEL automatically killed when the Viewer exits use the
|
|
-killstunnel cmdline option, or set it under Options or in ssvnc_rc.
|
|
}
|
|
.w.t insert end $msg
|
|
}
|
|
|
|
proc win9x_plink_msg {file} {
|
|
global help_font win9x_plink_msg_done
|
|
toplev .pl
|
|
|
|
eval text .pl.t -width 90 -height 26 $help_font
|
|
button .pl.d -text "OK" -command {destroy .pl; set win9x_plink_msg_done 1}
|
|
wm protocol .pl WM_DELETE_WINDOW {catch {destroy .pl}; set win9x_plink_msg_done 1}
|
|
pack .pl.t .pl.d -side top -fill x
|
|
|
|
apply_bg .pl.t
|
|
|
|
center_win .pl
|
|
wm resizable .pl 1 0
|
|
|
|
wm title .pl "SSL/SSH Viewer: Win9x Warning"
|
|
|
|
set msg {
|
|
Due to limitations on Window 9x you will have to manually start up
|
|
a COMMAND.COM terminal and paste in the following command:
|
|
|
|
}
|
|
set pwd [pwd]
|
|
regsub -all {/} $pwd "\\" pwd
|
|
append msg " $pwd\\$file\n"
|
|
|
|
append msg {
|
|
The reason for this is a poor Console application implementation that
|
|
affects many text based applications.
|
|
|
|
To start up a COMMAND.COM terminal, click on the Start -> Run, and then
|
|
type COMMAND in the entry box and hit Return or click OK.
|
|
|
|
To select the above command, highlight it with the mouse and then press
|
|
Ctrl-C. Then go over to the COMMAND.COM window and click on the
|
|
Clipboard paste button. Once pasted in, press Return to run the script.
|
|
|
|
This will start up a PLINK.EXE ssh login to the remote computer,
|
|
and after you log in successfully and indicate (QUICKLY!!) that the
|
|
connection is OK by clicking OK in this dialog. If the SSH connection
|
|
cannot be autodetected you will ALSO need to click "Success" in the
|
|
"plink ssh status?" dialog, the VNC Viewer will be started going
|
|
through the SSH tunnel.
|
|
}
|
|
.pl.t insert end $msg
|
|
wm deiconify .pl
|
|
}
|
|
|
|
proc mesg {str} {
|
|
set maxx 60
|
|
if [regexp {^INFO: without Certificate} $str] {
|
|
set maxx 72
|
|
}
|
|
if {[string length $str] > $maxx} {
|
|
set lend [expr $maxx - 1]
|
|
set str [string range $str 0 $lend]
|
|
append str " ..."
|
|
}
|
|
.l configure -text $str
|
|
update
|
|
global env
|
|
if [info exists env(SSVNC_MESG_DELAY)] {
|
|
after $env(SSVNC_MESG_DELAY)
|
|
}
|
|
}
|
|
|
|
proc get_ssh_hp {str} {
|
|
regsub {cmd=.*$} $str "" str
|
|
set str [string trim $str]
|
|
regsub {[ ].*$} $str "" str
|
|
return $str
|
|
}
|
|
|
|
proc get_ssh_cmd {str} {
|
|
set str [string trim $str]
|
|
global ts_only
|
|
if {$ts_only} {
|
|
return [ts_x11vnc_cmd]
|
|
}
|
|
if [regexp {cmd=(.*$)} $str m cmd] {
|
|
set cmd [string trim $cmd]
|
|
regsub -nocase {^%x11vncr$} $cmd "x11vnc -nopw -display none -rawfb rand" cmd
|
|
regsub -nocase {^%x11vnc$} $cmd "x11vnc -nopw -display none -rawfb null" cmd
|
|
return $cmd
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
proc get_ssh_proxy {str} {
|
|
set str [string trim $str]
|
|
regsub {cmd=.*$} $str "" str
|
|
set str [string trim $str]
|
|
if { ![regexp {[ ]} $str]} {
|
|
return ""
|
|
}
|
|
regsub {^.*[ ][ ]*} $str "" str
|
|
return $str
|
|
}
|
|
|
|
proc ts_x11vnc_cmd {} {
|
|
global is_windows
|
|
global ts_xserver_type choose_xserver ts_desktop_type choose_desktop ts_unixpw ts_vncshared
|
|
global ts_desktop_size ts_desktop_depth choose_desktop_geom
|
|
global choose_filexfer ts_filexfer
|
|
global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts
|
|
global ts_othervnc choose_othervnc ts_xlogin
|
|
global choose_sleep extra_sleep
|
|
|
|
set cmd ""
|
|
if {$choose_x11vnc_opts && $ts_x11vnc_path != ""} {
|
|
set cmd $ts_x11vnc_path
|
|
} else {
|
|
set cmd "x11vnc"
|
|
}
|
|
if {! $is_windows} {
|
|
set cmd "PORT= $cmd"
|
|
} else {
|
|
set cmd "PORT= $cmd"
|
|
}
|
|
|
|
set type $ts_xserver_type;
|
|
if {! $choose_xserver} {
|
|
set type ""
|
|
}
|
|
if {$choose_othervnc && $ts_othervnc == "find"} {
|
|
set type "Xvnc.redirect"
|
|
}
|
|
|
|
if [info exists choose_sleep] {
|
|
if {! $choose_sleep} {
|
|
set extra_sleep ""
|
|
}
|
|
}
|
|
|
|
if {$choose_othervnc && $ts_othervnc != "find"} {
|
|
set cmd "$cmd -redirect $ts_othervnc"
|
|
} elseif {$type == ""} {
|
|
global ts_xserver_type_def
|
|
if {$ts_xserver_type_def != ""} {
|
|
set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-$ts_xserver_type_def";
|
|
} else {
|
|
set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb";
|
|
}
|
|
} elseif {$type == "Xvfb"} {
|
|
set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb";
|
|
} elseif {$type == "Xdummy"} {
|
|
set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xdummy";
|
|
} elseif {$type == "Xvnc"} {
|
|
set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc";
|
|
} elseif {$type == "Xvnc.redirect"} {
|
|
set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect";
|
|
}
|
|
|
|
# TBD: Cups + sound
|
|
|
|
set cmd "$cmd -localhost";
|
|
set cmd "$cmd -nopw";
|
|
global ts_ncache choose_ncache
|
|
if {$choose_ncache && [regexp {^[0-9][0-9]*$} $ts_ncache]} {
|
|
set cmd "$cmd -ncache $ts_ncache";
|
|
} else {
|
|
#set cmd "$cmd -nonc";
|
|
}
|
|
set cmd "$cmd -timeout 120";
|
|
global ts_multisession choose_multisession
|
|
regsub -all {[^A-z0-9_-]} $ts_multisession "" ts_multisession
|
|
if {$choose_multisession && $ts_multisession != ""} {
|
|
set cmd "$cmd -env FD_TAG='$ts_multisession'";
|
|
}
|
|
if {$choose_filexfer && $ts_filexfer != ""} {
|
|
if {$ts_filexfer == "tight"} {
|
|
set cmd "$cmd -tightfilexfer";
|
|
} else {
|
|
set cmd "$cmd -ultrafilexfer";
|
|
}
|
|
}
|
|
if {$ts_unixpw} {
|
|
set cmd "$cmd -unixpw";
|
|
}
|
|
if {$ts_vncshared} {
|
|
set cmd "$cmd -shared";
|
|
}
|
|
set u "unknown"
|
|
global env
|
|
if {[info exists env(USER)]} {
|
|
regsub -all {[^A-z]} $env(USER) "_" u
|
|
}
|
|
set cmd "$cmd -o \$HOME/.tsvnc.log.$u"; # XXX perms
|
|
|
|
set sess "kde"
|
|
global ts_desktop_type_def
|
|
if {$ts_desktop_type_def != ""} {
|
|
set sess $ts_desktop_type_def
|
|
}
|
|
if {$choose_desktop && $ts_desktop_type != ""} {
|
|
set sess $ts_desktop_type
|
|
}
|
|
set cmd "$cmd -env FD_SESS=$sess";
|
|
|
|
if {$choose_desktop_geom} {
|
|
set geom "1280x1024"
|
|
set dep 16
|
|
global ts_desktop_size_def ts_desktop_depth_def
|
|
if {$ts_desktop_size_def != ""} {
|
|
set geom $ts_desktop_size_def
|
|
}
|
|
if {$ts_desktop_depth_def != ""} {
|
|
set dep $ts_desktop_depth_def
|
|
}
|
|
if {$ts_desktop_size != ""} {
|
|
if [regexp {^[0-9][0-9]*x[0-9][0-9]*$} $ts_desktop_size] {
|
|
set geom $ts_desktop_size
|
|
}
|
|
if {$ts_desktop_depth != ""} {
|
|
set geom "${geom}x$ts_desktop_depth"
|
|
} else {
|
|
set geom "${geom}x$dep"
|
|
}
|
|
} else {
|
|
set geom "${geom}x$dep"
|
|
}
|
|
set cmd "$cmd -env FD_GEOM=$geom";
|
|
}
|
|
if {$is_windows} {
|
|
;
|
|
} elseif {$choose_x11vnc_opts && $ts_x11vnc_autoport != "" && [regexp {^[0-9][0-9]*$} $ts_x11vnc_autoport]} {
|
|
set cmd "$cmd -autoport $ts_x11vnc_autoport";
|
|
} else {
|
|
set cmd "$cmd -env AUTO_PORT=5950";
|
|
}
|
|
if {$choose_x11vnc_opts && $ts_x11vnc_opts != ""} {
|
|
set cmd "$cmd $ts_x11vnc_opts";
|
|
}
|
|
if {$ts_xlogin} {
|
|
regsub {PORT= } $cmd "PORT= sudo " cmd
|
|
regsub {P= } $cmd "P= sudo " cmd
|
|
regsub { -o [^ ][^ ]*} $cmd "" cmd
|
|
|
|
set cmd "$cmd -env FD_XDM=1";
|
|
}
|
|
|
|
return $cmd
|
|
}
|
|
|
|
proc set_defaults {} {
|
|
global defs env
|
|
|
|
global mycert svcert crtdir crlfil
|
|
global use_alpha use_turbovnc disable_pipeline use_grab use_ssl use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
|
|
global use_send_clipboard use_send_always
|
|
global disable_all_encryption
|
|
global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
|
|
global compresslevel_text quality_text
|
|
global use_cups use_sound use_smbmnt
|
|
global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc
|
|
global cups_local_smb_server cups_remote_smb_port
|
|
global change_vncviewer change_vncviewer_path vncviewer_realvnc4
|
|
global choose_xserver ts_xserver_type choose_desktop ts_desktop_type ts_unixpw ts_vncshared
|
|
global choose_filexfer ts_filexfer
|
|
global ts_x11vnc_opts choose_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport ts_xlogin
|
|
global ts_othervnc choose_othervnc choose_sleep
|
|
global choose_ncache ts_ncache choose_multisession ts_multisession
|
|
global ts_mode ts_desktop_size ts_desktop_depth choose_desktop_geom
|
|
global additional_port_redirs additional_port_redirs_list
|
|
global stunnel_local_protection stunnel_local_protection_type ssh_local_protection multiple_listen listen_once listen_accept_popup listen_accept_popup_sc
|
|
global ssh_known_hosts ssh_known_hosts_filename
|
|
global ultra_dsm ultra_dsm_type ultra_dsm_file ultra_dsm_noultra ultra_dsm_salt
|
|
global sound_daemon_remote_cmd sound_daemon_remote_port sound_daemon_kill sound_daemon_restart
|
|
global sound_daemon_local_cmd sound_daemon_local_port sound_daemon_local_kill sound_daemon_x11vnc sound_daemon_local_start
|
|
global smb_su_mode smb_mount_list
|
|
global use_port_knocking port_knocking_list port_slot putty_args
|
|
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
|
|
global disable_ssl_workarounds disable_ssl_workarounds_type
|
|
global no_probe_vencrypt server_vencrypt server_anondh
|
|
global include_list
|
|
global svcert_default mycert_default crlfil_default
|
|
|
|
|
|
set defs(use_viewonly) 0
|
|
set defs(use_listen) 0
|
|
set defs(disable_ssl_workarounds) 0
|
|
set defs(disable_ssl_workarounds_type) "none"
|
|
set defs(use_unixpw) 0
|
|
set defs(unixpw_username) ""
|
|
set defs(use_x11vnc_find) 0
|
|
set defs(use_fullscreen) 0
|
|
set defs(use_raise_on_beep) 0
|
|
set defs(use_bgr233) 0
|
|
set defs(use_alpha) 0
|
|
set defs(use_send_clipboard) 0
|
|
set defs(use_send_always) 0
|
|
set defs(use_turbovnc) 0
|
|
set defs(disable_pipeline) 0
|
|
set defs(no_probe_vencrypt) 0
|
|
set defs(server_vencrypt) 0
|
|
set defs(server_anondh) 0
|
|
set defs(use_grab) 0
|
|
set defs(use_nojpeg) 0
|
|
set defs(use_x11_macosx) 1
|
|
if [info exists env(SSVNC_COTVNC)] {
|
|
if {$env(SSVNC_COTVNC) != 0} {
|
|
set defs(use_x11_macosx) 0
|
|
}
|
|
} elseif {![info exists env(DISPLAY)]} {
|
|
set defs(use_x11_macosx) 0
|
|
}
|
|
set defs(use_compresslevel) "default"
|
|
set defs(use_quality) "default"
|
|
set defs(compresslevel_text) "Compress Level: default"
|
|
set defs(quality_text) "Quality: default"
|
|
|
|
set defs(mycert) $mycert_default
|
|
set defs(svcert) $svcert_default
|
|
set defs(crtdir) "ACCEPTED_CERTS"
|
|
set defs(crlfil) $crlfil_default
|
|
|
|
set defs(use_cups) 0
|
|
set defs(use_sound) 0
|
|
set defs(use_smbmnt) 0
|
|
|
|
set defs(choose_xserver) 0
|
|
set defs(ts_xserver_type) ""
|
|
set defs(choose_desktop) 0
|
|
set defs(ts_desktop_type) ""
|
|
set defs(ts_desktop_size) ""
|
|
set defs(ts_desktop_depth) ""
|
|
set defs(choose_desktop_geom) 0
|
|
set defs(ts_unixpw) 0
|
|
set defs(ts_vncshared) 0
|
|
set defs(ts_ncache) 8
|
|
set defs(choose_ncache) 0
|
|
set defs(ts_multisession) ""
|
|
set defs(choose_multisession) 0
|
|
set defs(ts_filexfer) ""
|
|
set defs(choose_filexfer) 0
|
|
set defs(choose_x11vnc_opts) 0
|
|
set defs(ts_x11vnc_opts) ""
|
|
set defs(ts_x11vnc_path) ""
|
|
set defs(ts_x11vnc_autoport) ""
|
|
set defs(ts_othervnc) ""
|
|
set defs(choose_othervnc) 0
|
|
set defs(ts_xlogin) 0
|
|
set defs(ts_mode) 0
|
|
|
|
set defs(change_vncviewer) 0
|
|
set defs(change_vncviewer_path) ""
|
|
set defs(cups_manage_rcfile) 1
|
|
set defs(ts_cups_manage_rcfile) 0
|
|
set defs(cups_x11vnc) 0
|
|
set defs(vncviewer_realvnc4) 0
|
|
|
|
set defs(additional_port_redirs) 0
|
|
set defs(additional_port_redirs_list) ""
|
|
|
|
set defs(stunnel_local_protection) 1
|
|
set defs(stunnel_local_protection_type) "exec"
|
|
set defs(ssh_local_protection) 1
|
|
set defs(ssh_known_hosts) 0
|
|
set defs(ssh_known_hosts_filename) ""
|
|
set defs(multiple_listen) 0
|
|
set defs(listen_once) 0
|
|
set defs(listen_accept_popup) 0
|
|
set defs(listen_accept_popup_sc) 0
|
|
|
|
set defs(ultra_dsm) 0
|
|
set defs(ultra_dsm_file) ""
|
|
set defs(ultra_dsm_type) "guess"
|
|
set defs(ultra_dsm_noultra) 0
|
|
set defs(ultra_dsm_salt) ""
|
|
|
|
set defs(port_slot) ""
|
|
set defs(putty_args) ""
|
|
|
|
set defs(cups_local_server) ""
|
|
set defs(cups_remote_port) ""
|
|
set defs(cups_local_smb_server) ""
|
|
set defs(cups_remote_smb_port) ""
|
|
|
|
set defs(smb_su_mode) "sudo"
|
|
set defs(smb_mount_list) ""
|
|
|
|
set defs(sound_daemon_remote_cmd) ""
|
|
set defs(sound_daemon_remote_port) ""
|
|
set defs(sound_daemon_kill) 0
|
|
set defs(sound_daemon_restart) 0
|
|
|
|
set defs(sound_daemon_local_cmd) ""
|
|
set defs(sound_daemon_local_port) ""
|
|
set defs(sound_daemon_local_start) 0
|
|
set defs(sound_daemon_local_kill) 0
|
|
set defs(sound_daemon_x11vnc) 0
|
|
|
|
set defs(ycrop_string) ""
|
|
set defs(ssvnc_scale) ""
|
|
set defs(ssvnc_escape) ""
|
|
set defs(sbwid_string) ""
|
|
set defs(rfbversion) ""
|
|
set defs(ssvnc_encodings) ""
|
|
set defs(ssvnc_extra_opts) ""
|
|
set defs(use_x11cursor) 0
|
|
set defs(use_nobell) 0
|
|
set defs(use_rawlocal) 0
|
|
set defs(use_notty) 0
|
|
set defs(use_popupfix) 0
|
|
set defs(extra_sleep) ""
|
|
set defs(use_port_knocking) 0
|
|
set defs(port_knocking_list) ""
|
|
|
|
set defs(include_list) ""
|
|
|
|
set dir [get_profiles_dir]
|
|
set deffile ""
|
|
if [file exists "$dir/defaults"] {
|
|
set deffile "$dir/defaults"
|
|
} elseif [file exists "$dir/defaults.vnc"] {
|
|
set deffile "$dir/defaults.vnc"
|
|
}
|
|
if {$deffile != ""} {
|
|
set fh ""
|
|
catch {set fh [open $deffile "r"]}
|
|
if {$fh != ""} {
|
|
while {[gets $fh line] > -1} {
|
|
set line [string trim $line]
|
|
if [regexp {^#} $line] {
|
|
continue
|
|
}
|
|
if [regexp {^([^=]*)=(.*)$} $line m var val] {
|
|
if {$var == "disp"} {
|
|
continue
|
|
}
|
|
if [info exists defs($var)] {
|
|
set pct 0
|
|
if {$var == "smb_mount_list"} {
|
|
set pct 1
|
|
}
|
|
if {$var == "port_knocking_list"} {
|
|
set pct 1
|
|
}
|
|
if {$pct} {
|
|
regsub -all {%%%} $val "\n" val
|
|
}
|
|
set defs($var) $val
|
|
}
|
|
}
|
|
}
|
|
close $fh
|
|
}
|
|
}
|
|
|
|
global ssh_only ts_only
|
|
if {$ssh_only || $ts_only} {
|
|
set defs(use_ssl) 0
|
|
set defs(use_ssh) 1
|
|
set defs(use_sshssl) 0
|
|
} else {
|
|
set defs(use_ssl) 1
|
|
set defs(use_ssh) 0
|
|
set defs(use_sshssl) 0
|
|
}
|
|
set defs(disable_all_encryption) 0
|
|
|
|
foreach var [array names defs] {
|
|
set $var $defs($var)
|
|
}
|
|
|
|
global vncauth_passwd unixpw_passwd
|
|
set vncauth_passwd ""
|
|
set unixpw_passwd ""
|
|
|
|
if {$ssh_only || $ts_only} {
|
|
ssl_ssh_adjust ssh
|
|
} else {
|
|
ssl_ssh_adjust ssl
|
|
}
|
|
listen_adjust
|
|
unixpw_adjust
|
|
|
|
global last_load
|
|
set last_load ""
|
|
}
|
|
|
|
proc windows_listening_message {n} {
|
|
global did_listening_message
|
|
|
|
global extra_cmd
|
|
set extra_cmd ""
|
|
set cmd [get_cmd $n]
|
|
|
|
if {$did_listening_message < 2} {
|
|
incr did_listening_message
|
|
global listening_name
|
|
|
|
set ln $listening_name
|
|
if {$ln == ""} {
|
|
set ln "this-computer:$n"
|
|
}
|
|
|
|
set msg "
|
|
About to start the Listening VNC Viewer (Reverse Connection).
|
|
|
|
The VNC Viewer command to be run is:
|
|
|
|
$cmd
|
|
|
|
After the Viewer starts listening, the VNC server should
|
|
then Reverse connect to:
|
|
|
|
$ln
|
|
|
|
When the VNC Connection has ended **YOU MUST MANUALLY STOP**
|
|
the Listening VNC Viewer.
|
|
|
|
To stop the Listening Viewer: right click on the VNC Icon in
|
|
the tray and select 'Close listening daemon' (or similar).
|
|
|
|
ONLY AFTER THAT will you return to the SSVNC GUI.
|
|
|
|
Click OK now to start the Listening VNC Viewer.$extra_cmd
|
|
"
|
|
global use_ssh use_sshssl
|
|
if {$use_ssh || $use_sshssl} {
|
|
set msg "${msg} NOTE: You will probably also need to kill the SSH in the\n terminal via Ctrl-C"
|
|
}
|
|
|
|
global help_font is_windows system_button_face
|
|
toplev .wll
|
|
global wll_done
|
|
|
|
set wll_done 0
|
|
|
|
eval text .wll.t -width 64 -height 22 $help_font
|
|
button .wll.d -text "OK" -command {destroy .wll; set wll_done 1}
|
|
pack .wll.t .wll.d -side top -fill x
|
|
|
|
apply_bg .wll.t
|
|
|
|
center_win .wll
|
|
wm resizable .wll 1 0
|
|
|
|
wm title .wll "SSL/SSH Viewer: Listening VNC Info"
|
|
|
|
.wll.t insert end $msg
|
|
|
|
vwait wll_done
|
|
}
|
|
}
|
|
|
|
proc get_cmd {n} {
|
|
global use_alpha use_grab use_x11cursor use_nobell use_ssh
|
|
global use_sshssl use_viewonly use_fullscreen use_bgr233
|
|
global use_nojpeg use_raise_on_beep use_compresslevel use_quality
|
|
global use_send_clipboard use_send_always change_vncviewer
|
|
global change_vncviewer_path vncviewer_realvnc4 use_listen
|
|
global disable_ssl_workarounds disable_ssl_workarounds_type env
|
|
|
|
set cmd "vncviewer"
|
|
if {$change_vncviewer && $change_vncviewer_path != ""} {
|
|
set cmd [string trim $change_vncviewer_path]
|
|
regsub -all {\\} $cmd {/} cmd
|
|
if {[regexp {[ \t]} $cmd]} {
|
|
if {[regexp -nocase {\.exe$} $cmd]} {
|
|
if {! [regexp {["']} $cmd]} { #"
|
|
# hmmm, not following instructions, are they?
|
|
set cmd "\"$cmd\""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if {$use_viewonly} {
|
|
if {$vncviewer_realvnc4} {
|
|
append cmd " viewonly=1"
|
|
} else {
|
|
append cmd " /viewonly"
|
|
}
|
|
}
|
|
if {$use_fullscreen} {
|
|
if {$vncviewer_realvnc4} {
|
|
append cmd " fullscreen=1"
|
|
} else {
|
|
append cmd " /fullscreen"
|
|
}
|
|
}
|
|
if {$use_bgr233} {
|
|
if {$vncviewer_realvnc4} {
|
|
append cmd " lowcolourlevel=1"
|
|
} else {
|
|
append cmd " /8bit"
|
|
}
|
|
}
|
|
if {$use_nojpeg} {
|
|
if {! $vncviewer_realvnc4} {
|
|
append cmd " /nojpeg"
|
|
}
|
|
}
|
|
if {$use_raise_on_beep} {
|
|
if {! $vncviewer_realvnc4} {
|
|
append cmd " /belldeiconify"
|
|
}
|
|
}
|
|
if {$use_compresslevel != "" && $use_compresslevel != "default"} {
|
|
if {$vncviewer_realvnc4} {
|
|
append cmd " zliblevel=$use_compresslevel"
|
|
} else {
|
|
append cmd " /compresslevel $use_compresslevel"
|
|
}
|
|
}
|
|
if {$use_quality != "" && $use_quality != "default"} {
|
|
if {! $vncviewer_realvnc4} {
|
|
append cmd " /quality $use_quality"
|
|
}
|
|
}
|
|
|
|
global extra_cmd
|
|
set extra_cmd ""
|
|
if {$use_listen} {
|
|
if {$vncviewer_realvnc4} {
|
|
append cmd " listen=1"
|
|
} else {
|
|
append cmd " /listen"
|
|
}
|
|
set nn $n
|
|
if {$nn < 100} {
|
|
set nn [expr "$nn + 5500"]
|
|
}
|
|
global direct_connect_reverse_host_orig is_win9x
|
|
if {![info exists direct_connect_reverse_host_orig]} {
|
|
set direct_connect_reverse_host_orig ""
|
|
}
|
|
if {$direct_connect_reverse_host_orig != "" && !$is_win9x} {
|
|
set nn2 [expr $nn + 15]
|
|
set h0 $direct_connect_reverse_host_orig
|
|
global win_localhost
|
|
set extra_cmd "\n\nrelay6.exe $nn $win_localhost $nn2 /b:$h0"
|
|
set nn $nn2
|
|
}
|
|
|
|
append cmd " $nn"
|
|
|
|
} else {
|
|
if [regexp {^[0-9][0-9]*$} $n] {
|
|
global win_localhost
|
|
append cmd " $win_localhost:$n"
|
|
} else {
|
|
append cmd " $n"
|
|
}
|
|
}
|
|
return $cmd
|
|
}
|
|
|
|
proc do_viewer_windows {n} {
|
|
global use_listen env
|
|
|
|
set cmd [get_cmd $n]
|
|
|
|
set ipv6_pid2 ""
|
|
if {$use_listen} {
|
|
set nn $n
|
|
if {$nn < 100} {
|
|
set nn [expr "$nn + 5500"]
|
|
}
|
|
global direct_connect_reverse_host_orig is_win9x
|
|
if {![info exists direct_connect_reverse_host_orig]} {
|
|
set direct_connect_reverse_host_orig ""
|
|
}
|
|
if {$direct_connect_reverse_host_orig != "" && !$is_win9x} {
|
|
set nn2 [expr $nn + 15]
|
|
set h0 $direct_connect_reverse_host_orig
|
|
global win_localhost
|
|
set ipv6_pid2 [exec relay6.exe $nn $win_localhost $nn2 /b:$h0 &]
|
|
set nn $nn2
|
|
}
|
|
}
|
|
|
|
if [info exists env(SSVNC_EXTRA_SLEEP)] {
|
|
set t $env(SSVNC_EXTRA_SLEEP)
|
|
mesg "sleeping an extra $t seconds..."
|
|
set t [expr "$t * 1000"]
|
|
after $t
|
|
}
|
|
global extra_sleep
|
|
if {$extra_sleep != ""} {
|
|
set t $extra_sleep
|
|
mesg "sleeping an extra $t seconds..."
|
|
set t [expr "$t * 1000"]
|
|
after $t
|
|
}
|
|
|
|
mesg $cmd
|
|
set emess ""
|
|
set rc [catch {eval exec $cmd} emess]
|
|
|
|
if {$ipv6_pid2 != ""} {
|
|
winkill $ipv6_pid2
|
|
}
|
|
|
|
if {$rc != 0} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message $emess -title "Error: $cmd"
|
|
}
|
|
}
|
|
|
|
proc get_netstat {} {
|
|
set ns ""
|
|
catch {set ns [exec netstat -an]}
|
|
return $ns
|
|
}
|
|
|
|
proc get_ipconfig {} {
|
|
global is_win9x
|
|
set ip ""
|
|
if {! $is_win9x} {
|
|
catch {set ip [exec ipconfig]}
|
|
return $ip
|
|
}
|
|
|
|
set file "ip"
|
|
append file [pid]
|
|
append file ".txt"
|
|
|
|
# VF
|
|
catch {[exec winipcfg /Batch $file]}
|
|
|
|
if [file exists $file] {
|
|
set fh [open $file "r"]
|
|
while {[gets $fh line] > -1} {
|
|
append ip "$line\n"
|
|
}
|
|
close $fh
|
|
catch {file delete $file}
|
|
}
|
|
return $ip
|
|
}
|
|
|
|
proc read_file {file} {
|
|
set str ""
|
|
if [file exists $file] {
|
|
set fh ""
|
|
catch {set fh [open $file "r"]}
|
|
if {$fh != ""} {
|
|
while {[gets $fh line] > -1} {
|
|
append str "$line\n"
|
|
}
|
|
close $fh
|
|
}
|
|
}
|
|
return $str
|
|
}
|
|
|
|
proc guess_nat_ip {} {
|
|
global save_nat last_save_nat
|
|
set s ""
|
|
|
|
if {! [info exists save_nat]} {
|
|
set save_nat ""
|
|
set last_save_nat 0
|
|
}
|
|
if {$save_nat != ""} {
|
|
set now [clock seconds]
|
|
if {$now < $last_save_nat + 45} {
|
|
return $save_nat
|
|
}
|
|
}
|
|
set s ""
|
|
catch {set s [socket "www.whatismyip.com" 80]}
|
|
set ip "unknown"
|
|
if {$s != ""} {
|
|
fconfigure $s -buffering none
|
|
#puts $s "GET / HTTP/1.1"
|
|
puts $s "GET /automation/n09230945.asp HTTP/1.1"
|
|
puts $s "Host: www.whatismyip.com"
|
|
puts $s "Connection: close"
|
|
puts $s ""
|
|
flush $s
|
|
set on 0
|
|
while { [gets $s line] > -1 } {
|
|
if {! $on && [regexp {<HEAD>} $line]} {set on 1}
|
|
if {! $on && [regexp {<HTML>} $line]} {set on 1}
|
|
if {! $on && [regexp {<TITLE>} $line]} {set on 1}
|
|
if {! $on && [regexp {^[0-9][0-9]*\.[0-9]} $line]} {set on 1}
|
|
if {! $on} {
|
|
continue;
|
|
}
|
|
if [regexp {([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*)} $line ip] {
|
|
break
|
|
}
|
|
}
|
|
close $s
|
|
}
|
|
if {$ip != "unknown"} {
|
|
set save_nat $ip
|
|
set last_save_nat [clock seconds]
|
|
}
|
|
return $ip
|
|
}
|
|
|
|
proc check_for_ipv6 {} {
|
|
global is_windows have_ipv6
|
|
if {$have_ipv6 != ""} {
|
|
return
|
|
}
|
|
if {! $is_windows} {
|
|
set out ""
|
|
catch {set out [exec netstat -an]}
|
|
if [regexp {tcp6} $out] {
|
|
set have_ipv6 1
|
|
} elseif [regexp {udp6} $out] {
|
|
set have_ipv6 1
|
|
} elseif [regexp {:::} $out] {
|
|
set have_ipv6 1
|
|
} elseif [regexp {::1} $out] {
|
|
set have_ipv6 1
|
|
} elseif [regexp {TCP: IPv6.*LISTEN} $out] {
|
|
set have_ipv6 1
|
|
} else {
|
|
set have_ipv6 0
|
|
}
|
|
} else {
|
|
set out [get_ipconfig]
|
|
set out [string trim $out]
|
|
if {$out == ""} {
|
|
catch {set out [exec ping6 -n 1 -w 2000 ::1]}
|
|
if [regexp {Reply from.*bytes} $out] {
|
|
if [regexp {Received = 1} $out] {
|
|
set have_ipv6 1
|
|
return
|
|
}
|
|
}
|
|
set have_ipv6 0
|
|
return
|
|
}
|
|
foreach line [split $out "\n\r"] {
|
|
if {[regexp -nocase {IP Address.*:[ \t]*[a-f0-9]*:[a-f0-9]*:} $line]} {
|
|
set have_ipv6 1
|
|
return
|
|
}
|
|
}
|
|
set have_ipv6 0
|
|
}
|
|
}
|
|
proc guess_ip {} {
|
|
global is_windows
|
|
if {! $is_windows} {
|
|
set out ""
|
|
set out [get_hostname]
|
|
if {$out != ""} {
|
|
set hout ""
|
|
catch {set hout [exec host $out]}
|
|
if {$hout != ""} {
|
|
if [regexp {has address ([.0-9][.0-9]*)} $hout mvar ip] {
|
|
set ip [string trim $ip]
|
|
return $ip
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
} else {
|
|
set out [get_ipconfig]
|
|
set out [string trim $out]
|
|
if {$out == ""} {
|
|
return ""
|
|
}
|
|
foreach line [split $out "\n\r"] {
|
|
if {[regexp -nocase {IP Address.*:[ \t]*([.0-9][.0-9]*)} $line mvar ip]} {
|
|
set ip [string trim $ip]
|
|
if [regexp {^[.0]*$} $ip] {
|
|
continue
|
|
}
|
|
if [regexp {127\.0\.0\.1} $ip] {
|
|
continue
|
|
}
|
|
if {$ip != ""} {
|
|
return $ip
|
|
}
|
|
}
|
|
}
|
|
foreach line [split $out "\n\r"] {
|
|
if {[regexp -nocase {IP Address.*:[ \t]*([:a-f0-9][%:a-f0-9]*)} $line mvar ip]} {
|
|
set ip [string trim $ip]
|
|
if [regexp {^[.0]*$} $ip] {
|
|
continue
|
|
}
|
|
if [regexp {127\.0\.0\.1} $ip] {
|
|
continue
|
|
}
|
|
if {$ip != ""} {
|
|
return $ip
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc bat_sleep {fh} {
|
|
global env
|
|
if [info exists env(SSVNC_BAT_SLEEP)] {
|
|
puts $fh "@echo ."
|
|
puts $fh "@echo -----"
|
|
puts $fh "@echo Debug: BAT SLEEP for $env(SSVNC_BAT_SLEEP) seconds ..."
|
|
puts $fh "@ping -n $env(SSVNC_BAT_SLEEP) -w 1000 0.0.0.1 > NUL"
|
|
puts $fh "@echo BAT SLEEP done."
|
|
}
|
|
}
|
|
|
|
proc windows_start_sound_daemon {file} {
|
|
global env
|
|
global use_sound sound_daemon_local_cmd sound_daemon_local_start
|
|
|
|
# VF
|
|
regsub {\.bat} $file "snd.bat" file2
|
|
set fh2 [open $file2 "w"]
|
|
|
|
puts $fh2 $sound_daemon_local_cmd
|
|
bat_sleep $fh2
|
|
puts $fh2 "del $file2"
|
|
close $fh2
|
|
|
|
mesg "Starting SOUND daemon..."
|
|
if [info exists env(COMSPEC)] {
|
|
if [info exists env(SSVNC_BAT_SLEEP)] {
|
|
exec $env(COMSPEC) /c start $env(COMSPEC) /c $file2 &
|
|
} else {
|
|
exec $env(COMSPEC) /c $file2 &
|
|
}
|
|
} else {
|
|
if [info exists env(SSVNC_BAT_SLEEP)] {
|
|
exec cmd.exe /c start cmd.exe /c $file2 &
|
|
} else {
|
|
exec cmd.exe /c $file2 &
|
|
}
|
|
}
|
|
after 1500
|
|
}
|
|
|
|
proc winkill {pid} {
|
|
global is_win9x
|
|
|
|
if {$pid == ""} {
|
|
return
|
|
}
|
|
if {! $is_win9x} {
|
|
catch {exec tskill.exe $pid}
|
|
after 100
|
|
catch {exec taskkill.exe /PID $pid}
|
|
after 100
|
|
}
|
|
catch {exec w98/kill.exe /f $pid}
|
|
}
|
|
|
|
proc windows_stop_sound_daemon {} {
|
|
global use_sound sound_daemon_local_cmd sound_daemon_local_start
|
|
|
|
set cmd [string trim $sound_daemon_local_cmd]
|
|
|
|
regsub {[ \t].*$} $cmd "" cmd
|
|
regsub {^.*\\} $cmd "" cmd
|
|
regsub {^.*/} $cmd "" cmd
|
|
|
|
if {$cmd == ""} {
|
|
return
|
|
}
|
|
|
|
set output [get_task_list]
|
|
|
|
foreach line [split $output "\n\r"] {
|
|
if [regexp "$cmd" $line] {
|
|
if [regexp {(-?[0-9][0-9]*)} $line m p] {
|
|
set pids($p) $line
|
|
}
|
|
}
|
|
}
|
|
|
|
set count 0
|
|
foreach pid [array names pids] {
|
|
mesg "Stopping SOUND pid: $pid"
|
|
winkill $pid
|
|
if {$count == 0} {
|
|
after 1200
|
|
} else {
|
|
after 500
|
|
}
|
|
incr count
|
|
}
|
|
}
|
|
|
|
proc contag {} {
|
|
global concount
|
|
if {! [info exists concount]} {
|
|
set concount 0
|
|
}
|
|
incr concount
|
|
set str [pid]
|
|
set str "-$str-$concount"
|
|
}
|
|
|
|
proc make_plink {} {
|
|
toplev .plink
|
|
#wm geometry .plink +700+500
|
|
wm geometry .plink -40-40
|
|
wm title .plink "plink SSH status?"
|
|
set wd 37
|
|
label .plink.l1 -anchor w -text "Login via plink/ssh to the remote server" -width $wd
|
|
label .plink.l2 -anchor w -text "(supply username and password as needed)." -width $wd
|
|
label .plink.l3 -anchor w -text "" -width $wd
|
|
label .plink.l4 -anchor w -text "After ssh is set up, AND if the connection" -width $wd
|
|
label .plink.l5 -anchor w -text "success is not autodetected, please click" -width $wd
|
|
label .plink.l6 -anchor w -text "one of these buttons:" -width $wd
|
|
global plink_status
|
|
button .plink.fail -text "Failed" -command {destroy .plink; set plink_status no}
|
|
button .plink.ok -text "Success" -command {destroy .plink; set plink_status yes}
|
|
pack .plink.l1 .plink.l2 .plink.l3 .plink.l4 .plink.l5 .plink.l6 .plink.fail .plink.ok -side top -fill x
|
|
|
|
update
|
|
}
|
|
|
|
proc ssh_split {str} {
|
|
regsub { .*$} $str "" str
|
|
if {! [regexp {:[0-9][0-9]*$} $str]} {
|
|
append str ":22"
|
|
}
|
|
regsub {:[0-9][0-9]*$} $str "" ssh_host
|
|
regsub {^.*:} $str "" ssh_port
|
|
if {$ssh_port == ""} {
|
|
set ssh_port 22
|
|
}
|
|
if [regexp {@} $ssh_host] {
|
|
regsub {@.*$} $ssh_host "" ssh_user
|
|
regsub {^.*@} $ssh_host "" ssh_host
|
|
} else {
|
|
set ssh_user ""
|
|
}
|
|
return [list $ssh_user $ssh_host $ssh_port]
|
|
}
|
|
|
|
proc check_debug_netstat {port str wn} {
|
|
global debug_netstat
|
|
if {! [info exists debug_netstat]} {
|
|
return
|
|
}
|
|
if {$debug_netstat == "0" || $debug_netstat == ""} {
|
|
return
|
|
}
|
|
mesg "DBG: $wn"
|
|
|
|
toplev .dbns
|
|
|
|
set h 35
|
|
if [small_height] {
|
|
set h 28
|
|
}
|
|
scroll_text_dismiss .dbns.f 82 $h
|
|
center_win .dbns
|
|
.dbns.f.t insert end "LOOKING FOR PORT: $port\n\n$str"
|
|
jiggle_text .dbns.f.t
|
|
update
|
|
after 1000
|
|
}
|
|
|
|
proc launch_windows_ssh {hp file n} {
|
|
global is_win9x env
|
|
global use_sshssl use_ssh putty_pw putty_args
|
|
global port_knocking_list
|
|
global use_listen listening_name
|
|
global disable_ssl_workarounds disable_ssl_workarounds_type
|
|
global ts_only
|
|
global debug_netstat
|
|
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
set sshcmd [get_ssh_cmd $hp]
|
|
|
|
global win_localhost
|
|
|
|
set vnc_host $win_localhost
|
|
set vnc_disp $hpnew
|
|
regsub {^.*:} $vnc_disp "" vnc_disp
|
|
|
|
regsub {\.bat} $file ".flg" flag
|
|
|
|
if {$ts_only} {
|
|
regsub {:0$} $hpnew "" hpnew
|
|
if {$proxy == ""} {
|
|
if {[regexp {^(.*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} {
|
|
set proxy "$sshhst:$sshpt"
|
|
set hpnew $win_localhost
|
|
}
|
|
} else {
|
|
if {![regexp {,} $proxy]} {
|
|
if {$hpnew != $win_localhost} {
|
|
set proxy "$proxy,$hpnew"
|
|
set hpnew $win_localhost
|
|
}
|
|
}
|
|
}
|
|
} elseif {![regexp {^-?[0-9][0-9]*$} $vnc_disp]} {
|
|
if {[regexp {cmd=SHELL} $hp]} {
|
|
;
|
|
} elseif {[regexp {cmd=PUTTY} $hp]} {
|
|
;
|
|
} else {
|
|
# XXX add :0 instead?
|
|
if {1} {
|
|
set vnc_disp "vnc_disp:0"
|
|
mesg "Added :0 to $vnc_disp"
|
|
} else {
|
|
mesg "Bad vncdisp, missing :0 ?, $vnc_disp"
|
|
bell
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
|
|
if {$use_listen} {
|
|
set vnc_port 5500
|
|
} else {
|
|
set vnc_port 5900
|
|
}
|
|
|
|
if {$ts_only || [regexp {PORT= .*x11vnc} $sshcmd] || [regexp {P= .*x11vnc} $sshcmd]} {
|
|
regsub {PORT= [ ]*} $sshcmd "" sshcmd
|
|
regsub {P= [ ]*} $sshcmd "" sshcmd
|
|
set vnc_port [expr "8100 + int(4000 * rand())"]
|
|
set sshcmd "$sshcmd -rfbport $vnc_port"
|
|
} elseif {[regexp {^-[0-9][0-9]*$} $vnc_disp]} {
|
|
set vnc_port [expr "- $vnc_disp"]
|
|
} elseif {![regexp {^[0-9][0-9]*$} $vnc_disp]} {
|
|
;
|
|
} elseif {$vnc_disp < 200} {
|
|
if {$use_listen} {
|
|
set vnc_port [expr $vnc_disp + 5500]
|
|
} else {
|
|
set vnc_port [expr $vnc_disp + 5900]
|
|
}
|
|
} else {
|
|
set vnc_port $vnc_disp
|
|
}
|
|
|
|
global ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
|
|
set ssh_port 22
|
|
set ssh_host [host_part $hpnew]
|
|
|
|
set double_ssh ""
|
|
set p_port ""
|
|
if {$proxy != ""} {
|
|
if [regexp -nocase {(http|https|socks|socks4|socks5|repeater)://} $proxy] {
|
|
set pproxy ""
|
|
set sproxy1 ""
|
|
set sproxy_rest ""
|
|
set sproxy1_host ""
|
|
set sproxy1_user ""
|
|
set sproxy1_port ""
|
|
foreach part [split $proxy ","] {
|
|
if {[regexp {^[ ]*$} $part]} {
|
|
continue
|
|
}
|
|
if [regexp -nocase {^(http|https|socks|socks4|socks5|repeater)://} $part] {
|
|
if {$pproxy == ""} {
|
|
set pproxy $part
|
|
} else {
|
|
set pproxy "$pproxy,$part"
|
|
}
|
|
} else {
|
|
if {$sproxy1 == ""} {
|
|
set sproxy1 $part
|
|
} else {
|
|
if {$sproxy_rest == ""} {
|
|
set sproxy_rest $part
|
|
} else {
|
|
set sproxy_rest "$sproxy_rest,$part"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#mesg "pproxy: $pproxy"; after 2000
|
|
#mesg "sproxy1: $sproxy1"; after 2000
|
|
#mesg "sproxy_rest: $sproxy_rest"; after 2000
|
|
#mesg "ssh_host: $ssh_host"; after 2000
|
|
#mesg "ssh_port: $ssh_port"; after 2000
|
|
|
|
if {$sproxy1 != ""} {
|
|
regsub {:[0-9][0-9]*$} $sproxy1 "" sproxy1_host
|
|
regsub {^.*@} $sproxy1_host "" sproxy1_host
|
|
regsub {@.*$} $sproxy1 "" sproxy1_user
|
|
regsub {^.*:} $sproxy1 "" sproxy1_port
|
|
} else {
|
|
regsub {:[0-9][0-9]*$} $ssh_host "" sproxy1_host
|
|
regsub {^.*@} $sproxy1_host "" sproxy1_host
|
|
regsub {@.*$} $ssh_host "" sproxy1_user
|
|
regsub {^.*:} $ssh_host "" sproxy1_port
|
|
}
|
|
if {![regexp {^[0-9][0-9]*$} $sproxy1_port]} {
|
|
set sproxy1_port 22
|
|
}
|
|
if {$sproxy1_user != ""} {
|
|
set sproxy1_user "$sproxy1_user@"
|
|
}
|
|
|
|
#mesg "sproxy1_host: $sproxy1_host"; after 2000
|
|
#mesg "sproxy1_user: $sproxy1_user"; after 2000
|
|
#mesg "sproxy1_port: $sproxy1_port"; after 2000
|
|
|
|
set port2 ""
|
|
if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] {
|
|
set port2 [expr 21000 + $dport]
|
|
} else {
|
|
set port2 [rand_port]
|
|
}
|
|
|
|
global have_ipv6
|
|
if {$have_ipv6} {
|
|
set res [ipv6_proxy $pproxy "" ""]
|
|
set pproxy [lindex $res 0]
|
|
set ssh_ipv6_pid [lindex $res 3]
|
|
}
|
|
|
|
set env(SSVNC_PROXY) $pproxy
|
|
set env(SSVNC_LISTEN) $port2
|
|
set env(SSVNC_DEST) "$sproxy1_host:$sproxy1_port"
|
|
|
|
mesg "Starting Proxy TCP helper on port $port2 ..."
|
|
after 300
|
|
# ssh br case:
|
|
set proxy_pid [exec "connect_br.exe" &]
|
|
|
|
catch { unset env(SSVNC_PROXY) }
|
|
catch { unset env(SSVNC_LISTEN) }
|
|
catch { unset env(SSVNC_DEST) }
|
|
|
|
if {$sproxy1 == ""} {
|
|
set proxy "$win_localhost:$port2"
|
|
if [regexp {^(.*)@} $ssh_host mv u] {
|
|
set proxy "$u@$proxy"
|
|
}
|
|
} else {
|
|
set proxy "${sproxy1_user}$win_localhost:$port2"
|
|
}
|
|
if {$sproxy_rest != ""} {
|
|
set proxy "$proxy,$sproxy_rest"
|
|
}
|
|
mesg "Set proxy to: $proxy"
|
|
after 300
|
|
}
|
|
if [regexp {,} $proxy] {
|
|
if {$is_win9x} {
|
|
mesg "Double proxy does not work on Win9x"
|
|
bell
|
|
winkill $ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
return 0
|
|
}
|
|
# user1@gateway:port1,user2@workstation:port2
|
|
set proxy1 ""
|
|
set proxy2 ""
|
|
set s [split $proxy ","]
|
|
set proxy1 [lindex $s 0]
|
|
set proxy2 [lindex $s 1]
|
|
|
|
set p_port ""
|
|
if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] {
|
|
set p_port [expr 4000 + $dport]
|
|
} else {
|
|
set p_port [expr 3000 + 1000 * rand()]
|
|
set p_port [expr round($p_port)]
|
|
}
|
|
|
|
set s [ssh_split $proxy1]
|
|
set ssh_user1 [lindex $s 0]
|
|
set ssh_host1 [lindex $s 1]
|
|
set ssh_port1 [lindex $s 2]
|
|
|
|
set s [ssh_split $proxy2]
|
|
set ssh_user2 [lindex $s 0]
|
|
set ssh_host2 [lindex $s 1]
|
|
set ssh_port2 [lindex $s 2]
|
|
|
|
if {! [regexp {^[0-9][0-9]*$} $ssh_port1]} {
|
|
set ssh_port1 22
|
|
}
|
|
if {! [regexp {^[0-9][0-9]*$} $ssh_port2]} {
|
|
set ssh_port2 22
|
|
}
|
|
|
|
set u1 ""
|
|
if {$ssh_user1 != ""} {
|
|
set u1 "${ssh_user1}@"
|
|
}
|
|
set u2 ""
|
|
if {$ssh_user2 != ""} {
|
|
set u2 "${ssh_user2}@"
|
|
}
|
|
|
|
set double_ssh "-L $p_port:$ssh_host2:$ssh_port2 -P $ssh_port1 $u1$ssh_host1"
|
|
set proxy_use "${u2}$win_localhost:$p_port"
|
|
|
|
} else {
|
|
# user1@gateway:port1
|
|
set proxy_use $proxy
|
|
}
|
|
|
|
set ssh_host [host_part $proxy_use]
|
|
|
|
set ssh_port [port_part $proxy_use]
|
|
if {! [regexp {^[0-9][0-9]*$} $ssh_port]} {
|
|
set ssh_port 22
|
|
}
|
|
|
|
set vnc_host [host_part $hpnew]
|
|
if {$vnc_host == ""} {
|
|
set vnc_host $win_localhost
|
|
}
|
|
}
|
|
|
|
if {![regexp {^[^ ][^ ]*@} $ssh_host]} {
|
|
mesg "You must supply a username: user@host..."
|
|
bell
|
|
winkill $ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
return 0
|
|
}
|
|
|
|
set verb "-v"
|
|
|
|
set pwd ""
|
|
if {$is_win9x} {
|
|
set pwd [pwd]
|
|
regsub -all {/} $pwd "\\" pwd
|
|
}
|
|
if {! [regexp {^[0-9][0-9]*$} $n]} {
|
|
set n 0
|
|
}
|
|
|
|
if {$use_listen} {
|
|
set use [expr $n + 5500]
|
|
} else {
|
|
set use [expr $n + 5900]
|
|
}
|
|
|
|
set_smb_mounts
|
|
|
|
global use_smbmnt use_sound sound_daemon_kill
|
|
set do_pre 0
|
|
if {$use_smbmnt} {
|
|
set do_pre 1
|
|
} elseif {$use_sound && $sound_daemon_kill} {
|
|
set do_pre 1
|
|
}
|
|
|
|
global skip_pre
|
|
if {$skip_pre} {
|
|
set do_pre 0
|
|
set skip_pre 0
|
|
}
|
|
|
|
set pw ""
|
|
if {$putty_pw != ""} {
|
|
if {! [regexp {"} $putty_pw]} { #"
|
|
set pw " -pw \"$putty_pw\""
|
|
}
|
|
}
|
|
|
|
set tag [contag]
|
|
|
|
set file_double ""
|
|
|
|
set file_pre ""
|
|
set file_pre_cmd ""
|
|
if {$do_pre} {
|
|
set setup_cmds [ugly_setup_scripts pre $tag]
|
|
|
|
if {$setup_cmds != ""} {
|
|
# VF
|
|
regsub {\.bat} $file "pre.cmd" file_pre_cmd
|
|
set fh [open $file_pre_cmd "w"]
|
|
puts $fh "$setup_cmds sleep 10; "
|
|
bat_sleep $fh
|
|
close $fh
|
|
|
|
# VF
|
|
regsub {\.bat} $file "pre.bat" file_pre
|
|
set fh [open $file_pre "w"]
|
|
set plink_str "plink.exe -ssh -C -P $ssh_port -m $file_pre_cmd $verb -t"
|
|
if {$putty_args != ""} {
|
|
append plink_str " $putty_args"
|
|
}
|
|
|
|
global smb_redir_0
|
|
if {$smb_redir_0 != ""} {
|
|
append plink_str " $smb_redir_0"
|
|
}
|
|
|
|
if [regexp {%} $ssh_host] {
|
|
set uath ""
|
|
regsub -all {%SPACE} $ssh_host " " uath
|
|
regsub -all {%TAB} $uath " " uath
|
|
append plink_str "$pw \"$uath\""
|
|
} else {
|
|
append plink_str "$pw $ssh_host"
|
|
}
|
|
|
|
if {$pw != ""} {
|
|
puts $fh "echo off"
|
|
}
|
|
puts $fh $plink_str
|
|
|
|
bat_sleep $fh
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
if {$file_pre_cmd != ""} {
|
|
puts $fh "del $file_pre_cmd"
|
|
}
|
|
puts $fh "del $file_pre"
|
|
}
|
|
close $fh
|
|
}
|
|
}
|
|
|
|
if {$is_win9x} {
|
|
set sleep 35
|
|
} else {
|
|
set sleep 20
|
|
}
|
|
if {$use_listen} {
|
|
set sleep 1800
|
|
}
|
|
|
|
set setup_cmds [ugly_setup_scripts post $tag]
|
|
|
|
set do_shell 0
|
|
if {$sshcmd == "SHELL"} {
|
|
set setup_cmds ""
|
|
set sshcmd {$SHELL}
|
|
set do_shell 1
|
|
} elseif {$sshcmd == "PUTTY"} {
|
|
set setup_cmds ""
|
|
set do_shell 1
|
|
}
|
|
|
|
if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} {
|
|
global use_cups cups_x11vnc cups_remote_port
|
|
global cups_remote_smb_port
|
|
global use_sound sound_daemon_x11vnc sound_daemon_remote_port
|
|
global ts_only
|
|
if {$ts_only} {
|
|
set cups_x11vnc 1
|
|
set sound_daemon_x11vnc 1
|
|
}
|
|
if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} {
|
|
set crp $cups_remote_port
|
|
if {$ts_only} {
|
|
set cups_remote_port [rand_port]
|
|
set crp "DAEMON-$cups_remote_port"
|
|
}
|
|
set sshcmd "$sshcmd -env FD_CUPS=$crp"
|
|
}
|
|
if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} {
|
|
set csp $cups_remote_smb_port
|
|
if {$ts_only} {
|
|
set cups_remote_smb_port [rand_port]
|
|
set csp "DAEMON-$cups_remote_smb_port"
|
|
}
|
|
set sshcmd "$sshcmd -env FD_SMB=$csp"
|
|
}
|
|
if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} {
|
|
set srp $sound_daemon_remote_port
|
|
if {$ts_only} {
|
|
set sound_daemon_remote_port [rand_port]
|
|
set srp "DAEMON-$sound_daemon_remote_port"
|
|
}
|
|
set sshcmd "$sshcmd -env FD_ESD=$srp"
|
|
}
|
|
}
|
|
|
|
set file_cmd ""
|
|
if {$setup_cmds != ""} {
|
|
# VF
|
|
regsub {\.bat} $file ".cmd" file_cmd
|
|
set fh_cmd [open $file_cmd "w"]
|
|
|
|
set str $setup_cmds
|
|
if {$sshcmd != ""} {
|
|
append str " $sshcmd; "
|
|
} else {
|
|
append str " sleep $sleep; "
|
|
}
|
|
puts $fh_cmd $str
|
|
bat_sleep $fh_cmd
|
|
close $fh_cmd
|
|
|
|
set sshcmd $setup_cmds
|
|
}
|
|
|
|
if {$sshcmd == ""} {
|
|
set pcmd "echo; echo SSH connected OK.; echo If this state is not autodetected,; echo Go Click the Success button."
|
|
set sshcmd "$pcmd; sleep $sleep"
|
|
}
|
|
|
|
global use_sound sound_daemon_local_cmd sound_daemon_local_start
|
|
if {! $do_shell && ! $is_win9x && $use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} {
|
|
windows_start_sound_daemon $file
|
|
}
|
|
|
|
# VF
|
|
set fh [open $file "w"]
|
|
if {$is_win9x} {
|
|
puts $fh "cd $pwd"
|
|
if {$file_pre != ""} {
|
|
puts $fh "echo Press Ctrl-C --HERE-- when done with the Pre-Command shell work."
|
|
puts $fh "start /w command.com /c $file_pre"
|
|
}
|
|
}
|
|
|
|
global use_cups use_smbmnt
|
|
set extra_redirs ""
|
|
if {$use_cups} {
|
|
append extra_redirs [get_cups_redir]
|
|
}
|
|
if {$use_sound} {
|
|
append extra_redirs [get_sound_redir]
|
|
}
|
|
global additional_port_redirs
|
|
if {$additional_port_redirs} {
|
|
append extra_redirs [get_additional_redir]
|
|
}
|
|
|
|
if {$vnc_host == ""} {
|
|
set vnc_host $win_localhost
|
|
}
|
|
regsub {^.*@} $vnc_host "" vnc_host
|
|
|
|
set redir "-L $use:$vnc_host:$vnc_port"
|
|
if {$use_listen} {
|
|
set redir "-R $vnc_port:$vnc_host:$use"
|
|
set listening_name "localhost:$vnc_port (on remote SSH side)"
|
|
}
|
|
|
|
set plink_str "plink.exe -ssh -P $ssh_port $verb $redir $extra_redirs -t"
|
|
if {$putty_args != ""} {
|
|
append plink_str " $putty_args"
|
|
}
|
|
if {$extra_redirs != ""} {
|
|
regsub {exe} $plink_str "exe -C" plink_str
|
|
} else {
|
|
# hmm we used to have it off... why?
|
|
# ssh typing response?
|
|
regsub {exe} $plink_str "exe -C" plink_str
|
|
}
|
|
set uath $ssh_host
|
|
if [regexp {%} $uath] {
|
|
regsub -all {%SPACE} $uath " " uath
|
|
regsub -all {%TAB} $uath " " uath
|
|
set uath "\"$uath\""
|
|
}
|
|
if {$do_shell} {
|
|
if {$sshcmd == "PUTTY"} {
|
|
if [regexp {^".*@} $uath] { #"
|
|
regsub {@} $uath {" "} uath
|
|
set uath "-l $uath"
|
|
}
|
|
if {$is_win9x} {
|
|
set plink_str "putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
|
|
} else {
|
|
set plink_str "start \"putty $ssh_host\" putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
|
|
if [regexp {FINISH} $port_knocking_list] {
|
|
regsub {start} $plink_str "start /wait" plink_str
|
|
}
|
|
}
|
|
} else {
|
|
set plink_str "plink.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
|
|
append plink_str { "$SHELL"}
|
|
}
|
|
} elseif {$file_cmd != ""} {
|
|
append plink_str " -m $file_cmd$pw $uath"
|
|
} else {
|
|
append plink_str "$pw $uath \"$sshcmd\""
|
|
}
|
|
|
|
if {$pw != ""} {
|
|
puts $fh "echo off"
|
|
}
|
|
if {$ts_only && [regexp {sudo } $sshcmd]} {
|
|
puts $fh "echo \" \""
|
|
puts $fh "echo \"Doing Initial SSH with sudo id to prime sudo...\""
|
|
puts $fh "echo \" \""
|
|
puts $fh "plink.exe -ssh $putty_args -t $uath \"sudo id; tty\""
|
|
puts $fh "echo \" \""
|
|
}
|
|
puts $fh $plink_str
|
|
bat_sleep $fh
|
|
puts $fh "del $flag"
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
if {$file_cmd != ""} {
|
|
puts $fh "del $file_cmd"
|
|
}
|
|
puts $fh "del $file"
|
|
}
|
|
close $fh
|
|
|
|
catch {destroy .o}
|
|
catch {destroy .oa}
|
|
catch {destroy .os}
|
|
|
|
if { ![do_port_knock $ssh_host start]} {
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
catch {file delete $file}
|
|
if {$file_cmd != ""} {
|
|
catch {file delete $file_cmd}
|
|
}
|
|
if {$file_pre != ""} {
|
|
catch {file delete $file_pre}
|
|
}
|
|
}
|
|
winkill $ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
return 0
|
|
}
|
|
|
|
if {$double_ssh != ""} {
|
|
set plink_str_double_ssh "plink.exe -ssh $putty_args -t $pw $double_ssh \"echo sleep 60 ...; sleep 60; echo done.\""
|
|
|
|
# VF
|
|
regsub {\.bat} $file "dob.bat" file_double
|
|
set fhdouble [open $file_double "w"]
|
|
puts $fhdouble $plink_str_double_ssh
|
|
bat_sleep $fhdouble
|
|
puts $fhdouble "del $flag"
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
puts $fhdouble "del $file_double"
|
|
}
|
|
close $fhdouble
|
|
|
|
set com "cmd.exe"
|
|
if [info exists env(COMSPEC)] {
|
|
set com $env(COMSPEC)
|
|
}
|
|
|
|
set ff [open $flag "w"]
|
|
puts $ff "flag"
|
|
close $ff
|
|
|
|
global env
|
|
if [info exists env(SSVNC_BAT_SLEEP)] {
|
|
exec $com /c start $com /c $file_double &
|
|
} else {
|
|
exec $com /c $file_double &
|
|
}
|
|
|
|
set waited 0
|
|
set gotit 0
|
|
while {$waited < 30000} {
|
|
after 500
|
|
update
|
|
if {$use_listen} {
|
|
set gotit 1
|
|
break;
|
|
}
|
|
set ns [get_netstat]
|
|
set re ":$p_port"
|
|
check_debug_netstat $p_port $ns $waited
|
|
append re {[ ][ ]*[0:.][0:.]*[ ][ ]*LISTEN}
|
|
if [regexp $re $ns] {
|
|
set gotit 1
|
|
break
|
|
}
|
|
set waited [expr "$waited + 500"]
|
|
if {![file exists $flag]} {
|
|
break
|
|
}
|
|
}
|
|
catch {file delete $flag}
|
|
if {! $gotit} {
|
|
after 5000
|
|
}
|
|
}
|
|
|
|
vencrypt_tutorial_mesg
|
|
|
|
set wdraw 1
|
|
#set wdraw 0
|
|
if [info exists debug_netstat] {
|
|
if {$debug_netstat != "" && $debug_netstat != "0"} {
|
|
set wdraw 0
|
|
}
|
|
}
|
|
|
|
set ff [open $flag "w"]
|
|
puts $ff "flag"
|
|
close $ff
|
|
|
|
if {$is_win9x} {
|
|
if {$wdraw} {
|
|
wm withdraw .
|
|
}
|
|
update
|
|
win9x_plink_msg $file
|
|
global win9x_plink_msg_done
|
|
set win9x_plink_msg_done 0
|
|
vwait win9x_plink_msg_done
|
|
} else {
|
|
set com "cmd.exe"
|
|
if [info exists env(COMSPEC)] {
|
|
set com $env(COMSPEC)
|
|
}
|
|
|
|
if {$file_pre != ""} {
|
|
set sl 0
|
|
if {$use_smbmnt} {
|
|
global smb_su_mode
|
|
if {$smb_su_mode == "su"} {
|
|
set sl [expr $sl + 15]
|
|
} elseif {$smb_su_mode == "sudo"} {
|
|
set sl [expr $sl + 15]
|
|
} else {
|
|
set sl [expr $sl + 3]
|
|
}
|
|
}
|
|
if {$pw == ""} {
|
|
set sl [expr $sl + 5]
|
|
}
|
|
|
|
set sl [expr $sl + 5]
|
|
set st [clock seconds]
|
|
set dt 0
|
|
global entered_gui_top button_gui_top
|
|
set entered_gui_top 0
|
|
set button_gui_top 0
|
|
|
|
catch {wm geometry . "-40-40"}
|
|
catch {wm withdraw .; update; wm deiconify .; raise .; update}
|
|
mesg "Click on *This* Label when done with 1st SSH 0/$sl"
|
|
after 600
|
|
|
|
global env
|
|
if [info exists env(SSVNC_BAT_SLEEP)] {
|
|
exec $com /c start $com /c $file_pre &
|
|
} else {
|
|
exec $com /c $file_pre &
|
|
}
|
|
|
|
catch {lower .; update; raise .; update}
|
|
|
|
while {$dt < $sl} {
|
|
after 100
|
|
set dt [clock seconds]
|
|
set dt [expr $dt - $st]
|
|
mesg "Click on *This* Label when done with 1st SSH $dt/$sl"
|
|
update
|
|
update idletasks
|
|
if {$dt <= 1} {
|
|
set button_gui_top 0
|
|
}
|
|
if {$button_gui_top != 0 && $dt >= 3} {
|
|
mesg "Running 2nd SSH now ..."
|
|
after 1000
|
|
break
|
|
}
|
|
}
|
|
mesg "Running 2nd SSH ..."
|
|
}
|
|
|
|
if {! $do_shell} {
|
|
make_plink
|
|
}
|
|
if {$wdraw} {
|
|
wm withdraw .
|
|
}
|
|
|
|
update
|
|
if {$do_shell && [regexp {FINISH} $port_knocking_list]} {
|
|
catch {exec $com /c $file}
|
|
} else {
|
|
global env
|
|
if [info exists env(SSVNC_BAT_SLEEP)] {
|
|
exec $com /c start $com /c $file &
|
|
} else {
|
|
exec $com /c $file &
|
|
}
|
|
}
|
|
after 1000
|
|
}
|
|
|
|
if {$do_shell} {
|
|
wm deiconify .
|
|
update
|
|
if {[regexp {FINISH} $port_knocking_list]} {
|
|
do_port_knock $ssh_host finish
|
|
}
|
|
return 1
|
|
}
|
|
set made_plink 0
|
|
if {$is_win9x} {
|
|
make_plink
|
|
set made_plink 1
|
|
}
|
|
global plink_status
|
|
set plink_status ""
|
|
set waited 0
|
|
set cnt 0
|
|
while {$waited < 30000} {
|
|
after 500
|
|
update
|
|
if {$use_listen} {
|
|
set plink_status yes
|
|
break;
|
|
}
|
|
set ns [get_netstat]
|
|
set re ":$use"
|
|
check_debug_netstat $use $ns $waited
|
|
append re {[ ][ ]*[0:.][0:.]*[ ][ ]*LISTEN}
|
|
if [regexp $re $ns] {
|
|
set plink_status yes
|
|
}
|
|
if {$plink_status != ""} {
|
|
catch {destroy .plink}
|
|
break
|
|
}
|
|
|
|
if {$waited == 0} {
|
|
#wm deiconify .plink
|
|
}
|
|
set waited [expr "$waited + 500"]
|
|
|
|
incr cnt
|
|
if {$cnt >= 12} {
|
|
set cnt 0
|
|
}
|
|
if {![file exists $flag]} {
|
|
set plink_status flag_gone
|
|
break
|
|
}
|
|
}
|
|
catch {file delete $flag}
|
|
if {$plink_status == ""} {
|
|
if {! $made_plink} {
|
|
make_plink
|
|
set made_plink 1
|
|
}
|
|
vwait plink_status
|
|
}
|
|
|
|
if {$use_sshssl} {
|
|
global launch_windows_ssh_files
|
|
if {$file != ""} {
|
|
append launch_windows_ssh_files "$file "
|
|
}
|
|
if {$file_pre != ""} {
|
|
append launch_windows_ssh_files "$file_pre "
|
|
}
|
|
if {$file_pre_cmd != ""} {
|
|
append launch_windows_ssh_files "$file_pre_cmd "
|
|
}
|
|
regsub { *$} $launch_windows_ssh_files "" launch_windows_ssh_files
|
|
return 1
|
|
}
|
|
|
|
if {$plink_status != "yes"} {
|
|
set m "unknown"
|
|
if {$plink_status == "flag_gone"} {
|
|
set m "plink script failed"
|
|
} elseif {$plink_status == ""} {
|
|
set m "timeout"
|
|
}
|
|
mesg "Error ($m) to $hp"
|
|
wm deiconify .
|
|
} else {
|
|
after 1000
|
|
do_viewer_windows $n
|
|
wm deiconify .
|
|
mesg "Disconnected from $hp"
|
|
}
|
|
update
|
|
if [regexp {FINISH} $port_knocking_list] {
|
|
do_port_knock $ssh_host finish
|
|
}
|
|
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
if {$file != ""} {
|
|
catch {file delete $file}
|
|
}
|
|
if {$file_pre != ""} {
|
|
catch {file delete $file_pre}
|
|
}
|
|
if {$file_pre_cmd != ""} {
|
|
catch {file delete $file_pre_cmd}
|
|
}
|
|
if {$file_double != ""} {
|
|
catch {file delete $file_double}
|
|
}
|
|
}
|
|
|
|
winkill $ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
|
|
global sound_daemon_local_kill
|
|
if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
|
|
windows_stop_sound_daemon
|
|
}
|
|
return 1
|
|
}
|
|
|
|
proc check_ssh_needed {} {
|
|
globalize
|
|
|
|
if {$use_ssh || $use_sshssl} {
|
|
return
|
|
}
|
|
set must_cups 0
|
|
set must_snd 0
|
|
set must_smb 0
|
|
set must_addl 0
|
|
if {$use_cups} {
|
|
if {$cups_local_server != ""} {set must_cups 1}
|
|
if {$cups_remote_port != ""} {set must_cups 1}
|
|
if {$cups_local_smb_server != ""} {set must_cups 1}
|
|
if {$cups_remote_smb_port != ""} {set must_cups 1}
|
|
if {$cups_manage_rcfile != ""} {set must_cups 1}
|
|
}
|
|
if {$use_sound} {
|
|
if {$sound_daemon_remote_cmd != ""} {set must_snd 1}
|
|
if {$sound_daemon_remote_port != ""} {set must_snd 1}
|
|
if {$sound_daemon_kill} {set must_snd 1}
|
|
if {$sound_daemon_restart} {set must_snd 1}
|
|
if {$sound_daemon_local_cmd != ""} {set must_snd 1}
|
|
if {$sound_daemon_local_port != ""} {set must_snd 1}
|
|
if {$sound_daemon_local_kill} {set must_snd 1}
|
|
if {$sound_daemon_local_start} {set must_snd 1}
|
|
}
|
|
if {$use_smbmnt} {
|
|
if {[regexp {//} $smb_mount_list]} {set must_smb 1}
|
|
}
|
|
if {$additional_port_redirs} {
|
|
set must_addl 1
|
|
}
|
|
if {$must_cups || $must_snd || $must_smb || $must_addl} {
|
|
mesg "Cannot do Port redirs in non-SSH mode (SSL)"
|
|
set msg ""
|
|
if {$must_smb} {
|
|
append msg " - SMB Mount Port Redirection\n"
|
|
}
|
|
if {$must_snd} {
|
|
append msg " - ESD Sound Port Redirection\n"
|
|
}
|
|
if {$must_cups} {
|
|
append msg " - CUPS Port Redirection\n"
|
|
}
|
|
if {$must_addl} {
|
|
append msg " - Additional Port Redirections\n"
|
|
}
|
|
set msg "\"Use SSL\" mode selected (no SSH)\nThe following options will be disabled:\n\n$msg"
|
|
bell
|
|
update
|
|
raise .
|
|
tk_messageBox -type ok -icon info -message $msg
|
|
}
|
|
}
|
|
|
|
proc set_smb_mounts {} {
|
|
global smb_redir_0 smb_mounts use_smbmnt
|
|
|
|
set smb_redir_0 ""
|
|
set smb_mounts ""
|
|
if {$use_smbmnt} {
|
|
set l2 [get_smb_redir]
|
|
set smb_redir_0 [lindex $l2 0]
|
|
set smb_redir_0 [string trim $smb_redir_0]
|
|
set smb_mounts [lindex $l2 1]
|
|
}
|
|
}
|
|
|
|
proc mytmp {tmp} {
|
|
global is_windows mktemp env
|
|
|
|
if {$is_windows} {
|
|
return $tmp
|
|
}
|
|
|
|
if {! [info exists mktemp]} {
|
|
set mktemp ""
|
|
foreach dir {/bin /usr/bin /usr/local/bin} {
|
|
if [file exists "$dir/mktemp"] {
|
|
set mktemp "$dir/mktemp"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if {$mktemp != ""} {
|
|
set tmp2 ""
|
|
catch {set tmp2 [exec $mktemp "$tmp.XXXXXX"]}
|
|
if [file exists $tmp2] {
|
|
if [info exists env(DEBUG_MKTEMP)] {
|
|
puts stderr "mytmp: $tmp2"
|
|
}
|
|
return $tmp2
|
|
}
|
|
}
|
|
catch {exec rm -f $tmp}
|
|
catch {file delete $tmp}
|
|
if [file exists $tmp] {
|
|
puts stderr "tmp file still exists: $tmp"
|
|
exit 1
|
|
}
|
|
catch {exec touch $tmp}
|
|
catch {exec chmod 600 $tmp}
|
|
if [info exists env(DEBUG_MKTEMP)] {
|
|
puts stderr "mytmp: $tmp"
|
|
}
|
|
return $tmp
|
|
}
|
|
|
|
proc darwin_terminal_cmd {{title ""} {cmd ""} {bg 0}} {
|
|
global darwin_terminal
|
|
|
|
set tries ""
|
|
lappend tries "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal"
|
|
|
|
if {! [info exists darwin_terminal]} {
|
|
foreach try $tries {
|
|
if [file exists $try] {
|
|
if [file executable $try] {
|
|
set darwin_terminal $try
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if {! [info exists darwin_terminal]} {
|
|
set fh ""
|
|
catch {set fh [open "| find /Applications -type f -name Terminal" "r"]}
|
|
if {$fh != ""} {
|
|
while {[gets $fh line] > -1} {
|
|
if {! [file exists $line]} {
|
|
continue
|
|
}
|
|
if {[file isdirectory $line]} {
|
|
continue
|
|
}
|
|
if {! [regexp {/Terminal$} $line]} {
|
|
continue
|
|
}
|
|
if {! [file executable $line]} {
|
|
continue
|
|
}
|
|
set darwin_terminal $line
|
|
break
|
|
}
|
|
close $fh
|
|
}
|
|
}
|
|
}
|
|
if {! [info exists darwin_terminal]} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message "Cannot find Darwin Terminal program." -title "Cannot find Terminal program"
|
|
mac_raise
|
|
return
|
|
}
|
|
|
|
global darwin_terminal_cnt
|
|
set tmp /tmp/darwin_terminal_cmd.[tpid]
|
|
if {! [info exists darwin_terminal_cnt]} {
|
|
set darwin_terminal_cnt 0
|
|
}
|
|
incr darwin_terminal_cnt
|
|
append tmp ".$darwin_terminal_cnt"
|
|
set tmp [mytmp $tmp]
|
|
|
|
set fh ""
|
|
catch {set fh [open $tmp w 0755]}
|
|
catch {[exec chmod 755 $tmp]}
|
|
if {$fh == ""} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message "Cannot open temporary file: $tmp" -title "Cannot open file"
|
|
mac_raise
|
|
return
|
|
}
|
|
global env
|
|
puts $fh "#!/bin/sh"
|
|
puts $fh "PATH=$env(PATH)"
|
|
puts $fh "export PATH"
|
|
puts $fh "tmp=$tmp"
|
|
puts $fh "sleep 1"
|
|
puts $fh {if [ "X$DDDBG" != "X" ]; then ps www; fi}
|
|
puts $fh {termpid=`ps www | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $1}' | sort -n | tail -1`}
|
|
puts $fh {echo try-1: termpid=$termpid mypid=$$}
|
|
puts $fh {if [ "X$termpid" = "X" ]; then}
|
|
puts $fh { termpid=`ps www | grep -w Terminal | grep -v grep | awk '{print $1}' | sort -n | tail -1`}
|
|
puts $fh { echo try-2: termpid=$termpid mypid=$$}
|
|
puts $fh {fi}
|
|
puts $fh {if [ "X$termpid" = "X" ]; then}
|
|
puts $fh { termpid=`ps wwwwaux | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $2}' | sort -n | tail -1`}
|
|
puts $fh { echo try-3: termpid=$termpid mypid=$$}
|
|
puts $fh {fi}
|
|
puts $fh {if [ "X$termpid" = "X" ]; then}
|
|
puts $fh { termpid=$$}
|
|
puts $fh { echo termpid-find-fail: termpid=$termpid mypid=$$}
|
|
puts $fh {fi}
|
|
puts $fh {trap "rm -f $tmp; kill -TERM $termpid; kill -TERM $mypid; kill -KILL $mypid; exit 0" 0 2 15}
|
|
puts $fh {osascript -e 'tell application "Terminal" to activate' >/dev/null 2>&1 &}
|
|
puts $fh "$cmd"
|
|
puts $fh "sleep 1"
|
|
puts $fh {rm -f $tmp}
|
|
puts $fh {kill -TERM $termpid}
|
|
puts $fh {kill -TERM $mypid}
|
|
puts $fh {kill -KILL $mypid}
|
|
puts $fh "exit 0"
|
|
close $fh
|
|
if {$bg} {
|
|
catch {exec $darwin_terminal $tmp &}
|
|
} else {
|
|
catch {exec $darwin_terminal $tmp}
|
|
}
|
|
}
|
|
|
|
proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo test"} {bg 0} {xrm1 ""} {xrm2 ""} {xrm3 ""}} {
|
|
global uname env
|
|
if {$uname == "Darwin"} {
|
|
global env
|
|
set doX 0;
|
|
if {! $doX} {
|
|
darwin_terminal_cmd $title $cmd $bg
|
|
return
|
|
}
|
|
}
|
|
|
|
global checked_for_xterm
|
|
if {![info exists checked_for_xterm]} {
|
|
set p ""
|
|
set r [catch {set p [exec /bin/sh -c {type xterm}]}]
|
|
set checked_for_xterm 1
|
|
if {$r != 0} {
|
|
set p [exec /bin/sh -c {type xterm 2>&1; exit 0}]
|
|
set txt "Problem finding the 'xterm' command:\n\n$p\n\n"
|
|
append txt "Perhaps you need to install a package containing 'xterm' (Sigh...)\n\n"
|
|
fetch_dialog $txt "xterm" "xterm" 0 [line_count $txt]
|
|
update
|
|
after 1000
|
|
catch {tkwait window .fetch}
|
|
update
|
|
}
|
|
}
|
|
|
|
if [info exists env(SSVNC_XTERM_REPLACEMENT)] {
|
|
set tcmd $env(SSVNC_XTERM_REPLACEMENT)
|
|
if {$tcmd != ""} {
|
|
regsub -all {%GEOMETRY} $tcmd $geometry tcmd
|
|
regsub -all {%TITLE} $tcmd $title tcmd
|
|
|
|
set tmp1 /tmp/xterm_replacement1.[tpid]
|
|
set tmp1 [mytmp $tmp1]
|
|
set fh1 ""
|
|
catch {set fh1 [open $tmp1 "w"]}
|
|
|
|
set tmp2 /tmp/xterm_replacement2.[tpid]
|
|
set tmp2 [mytmp $tmp2]
|
|
set fh2 ""
|
|
catch {set fh2 [open $tmp2 "w"]}
|
|
if {$fh1 != "" && $fh2 != ""} {
|
|
puts $fh1 "#!/bin/sh";
|
|
puts $fh1 "$cmd"
|
|
puts $fh1 "rm -f $tmp1"
|
|
close $fh1
|
|
catch {exec chmod 755 $tmp1}
|
|
puts $fh2 "#!/bin/sh"
|
|
puts $fh2 "$tcmd $tmp1"
|
|
puts $fh2 "rm -f $tmp2"
|
|
close $fh2
|
|
catch {exec chmod 755 $tmp2}
|
|
if {$bg} {
|
|
exec $tmp2 2>@stdout &
|
|
} else {
|
|
exec $tmp2 2>@stdout
|
|
}
|
|
return
|
|
}
|
|
catch {close $fh1}
|
|
catch {close $fh2}
|
|
}
|
|
}
|
|
|
|
if {$bg} {
|
|
if {$xrm1 == ""} {
|
|
exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout &
|
|
} else {
|
|
exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout &
|
|
}
|
|
} else {
|
|
if {$xrm1 == ""} {
|
|
exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout
|
|
} else {
|
|
exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout
|
|
}
|
|
}
|
|
}
|
|
|
|
proc xterm_center_geometry {} {
|
|
set sh [winfo screenheight .]
|
|
set sw [winfo screenwidth .]
|
|
set gw 500
|
|
set gh 300
|
|
set x [expr $sw/2 - $gw/2]
|
|
set y [expr $sh/2 - $gh/2]
|
|
if {$x < 0} {
|
|
set x 10
|
|
}
|
|
if {$y < 0} {
|
|
set y 10
|
|
}
|
|
|
|
return "+$x+$y"
|
|
}
|
|
|
|
proc smbmnt_wait {tee} {
|
|
if {$tee != ""} {
|
|
set start [clock seconds]
|
|
set cut 30
|
|
while {1} {
|
|
set now [clock seconds]
|
|
if {$now > $start + $cut} {
|
|
break;
|
|
}
|
|
if [file exists $tee] {
|
|
set sz 0
|
|
catch {set sz [file size $tee]}
|
|
if {$sz > 50} {
|
|
set cut 50
|
|
}
|
|
}
|
|
set g ""
|
|
catch {set g [exec grep main-vnc-helper-finished $tee]}
|
|
if [regexp {main-vnc-helper-finished} $g] {
|
|
break
|
|
}
|
|
after 1000
|
|
}
|
|
catch {file delete $tee}
|
|
} else {
|
|
global smb_su_mode
|
|
if {$smb_su_mode == "su"} {
|
|
after 15000
|
|
} elseif {$smb_su_mode == "sudo"} {
|
|
after 10000
|
|
}
|
|
}
|
|
}
|
|
|
|
proc do_unix_pre {tag proxy hp pk_hp} {
|
|
global env smb_redir_0 use_smbmnt
|
|
global did_port_knock
|
|
|
|
set setup_cmds [ugly_setup_scripts pre $tag]
|
|
set c "ss_vncviewer -ssh"
|
|
|
|
if {$proxy == ""} {
|
|
set pxy $hp
|
|
regsub {:[0-9][0-9]*$} $pxy "" pxy
|
|
set c "$c -proxy '$pxy'"
|
|
} else {
|
|
set c "$c -proxy '$proxy'"
|
|
}
|
|
|
|
if {$setup_cmds != ""} {
|
|
set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds sleep 10"
|
|
set env(SS_VNCVIEWER_SSH_ONLY) 1
|
|
if {$smb_redir_0 != ""} {
|
|
set c "$c -sshargs '$smb_redir_0'"
|
|
}
|
|
|
|
if {! [do_port_knock $pk_hp start]} {
|
|
return
|
|
}
|
|
set did_port_knock 1
|
|
|
|
if {$use_smbmnt} {
|
|
set title "SSL/SSH VNC Viewer $hp -- SMB MOUNTS"
|
|
} else {
|
|
set title "SSL/SSH VNC Viewer $hp -- Pre Commands"
|
|
}
|
|
|
|
set tee ""
|
|
if {$use_smbmnt} {
|
|
set tee $env(SSVNC_HOME)
|
|
append tee "/.tee-etv$tag"
|
|
set fh ""
|
|
catch {set fh [open $tee "w"]}
|
|
if {$fh == ""} {
|
|
set tee ""
|
|
} else {
|
|
close $fh
|
|
set c "$c | tee $tee"
|
|
}
|
|
}
|
|
|
|
unix_terminal_cmd "80x25+100+100" "$title" "set -xv; $c" 1
|
|
|
|
set env(SS_VNCVIEWER_SSH_CMD) ""
|
|
set env(SS_VNCVIEWER_SSH_ONLY) ""
|
|
|
|
if {$use_smbmnt} {
|
|
smbmnt_wait $tee
|
|
} else {
|
|
after 2000
|
|
}
|
|
}
|
|
}
|
|
proc init_vncdisplay {} {
|
|
global vncdisplay vncproxy remote_ssh_cmd
|
|
set vncdisplay [string trim $vncdisplay]
|
|
|
|
if {$vncdisplay == ""} {
|
|
set vncproxy ""
|
|
set remote_ssh_cmd ""
|
|
return
|
|
}
|
|
|
|
set hpnew [get_ssh_hp $vncdisplay]
|
|
set proxy [get_ssh_proxy $vncdisplay]
|
|
set sshcmd [get_ssh_cmd $vncdisplay]
|
|
|
|
set vncdisplay $hpnew
|
|
set vncproxy $proxy
|
|
set remote_ssh_cmd $sshcmd
|
|
|
|
global ssh_only ts_only
|
|
if {$sshcmd != "" || $ssh_only || $ts_only} {
|
|
global use_ssl use_ssh use_sshssl
|
|
set use_ssl 0
|
|
if {! $use_ssh && ! $use_sshssl} {
|
|
set use_ssh 1
|
|
}
|
|
}
|
|
# ssl_ssh_adjust will be called.
|
|
}
|
|
|
|
proc get_vncdisplay {} {
|
|
global vncdisplay vncproxy remote_ssh_cmd
|
|
set vncdisplay [string trim $vncdisplay]
|
|
|
|
set t $vncdisplay
|
|
regsub {[ \t]*cmd=.*$} $t "" t
|
|
set t [string trim $t]
|
|
|
|
set str ""
|
|
if [regexp {[ \t]} $t] {
|
|
set str $t
|
|
} else {
|
|
if {$vncproxy != "" && $t == ""} {
|
|
set str "--nohost-- $vncproxy"
|
|
} else {
|
|
set str "$t $vncproxy"
|
|
}
|
|
}
|
|
if [regexp {cmd=.*$} $vncdisplay match] {
|
|
if {$str == ""} {
|
|
set str "--nohost--"
|
|
}
|
|
set str "$str $match"
|
|
} else {
|
|
if {$remote_ssh_cmd != ""} {
|
|
if {$str == ""} {
|
|
set str "--nohost--"
|
|
}
|
|
set str "$str cmd=$remote_ssh_cmd"
|
|
}
|
|
}
|
|
set str [string trim $str]
|
|
return $str
|
|
}
|
|
|
|
proc port_knock_only {hp {mode KNOCK}} {
|
|
if {$hp == ""} {
|
|
set hp [get_vncdisplay]
|
|
if {$hp == ""} {
|
|
mesg "No host port found"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
set sshcmd [get_ssh_cmd $hp]
|
|
set hp $hpnew
|
|
|
|
set pk_hp ""
|
|
if {$proxy != ""} {
|
|
set pk_hp $proxy
|
|
}
|
|
if {$pk_hp == ""} {
|
|
set pk_hp $hp
|
|
}
|
|
if {$mode == "KNOCK"} {
|
|
do_port_knock $pk_hp start
|
|
} elseif {$mode == "FINISH"} {
|
|
do_port_knock $pk_hp finish
|
|
}
|
|
}
|
|
|
|
proc direct_connect_msg {} {
|
|
set msg ""
|
|
global env
|
|
globalize
|
|
if {$use_sshssl} {
|
|
append msg " - SSH + SSL tunnelling\n"
|
|
} elseif {$use_ssh} {
|
|
append msg " - SSH tunnelling\n"
|
|
} else {
|
|
append msg " - SSL tunnelling\n"
|
|
}
|
|
if [info exists env(SSVNC_NO_ENC_WARN)] {
|
|
set msg ""
|
|
}
|
|
if {$use_smbmnt} {
|
|
append msg " - SMB Mount Port Redirection\n"
|
|
}
|
|
if {$use_sound} {
|
|
append msg " - ESD Sound Port Redirection\n"
|
|
}
|
|
if {$use_cups} {
|
|
append msg " - CUPS Port Redirection\n"
|
|
}
|
|
if {$additional_port_redirs} {
|
|
append msg " - Additional Port Redirections\n"
|
|
}
|
|
if {$mycert != "" || $svcert != "" || $crtdir != ""} {
|
|
append msg " - SSL certificate authentication\n"
|
|
}
|
|
if {$msg != ""} {
|
|
set msg "Direct connect via vnc://hostname\nThe following options will be disabled:\n\n$msg"
|
|
raise .
|
|
tk_messageBox -type ok -icon info -message $msg
|
|
}
|
|
}
|
|
|
|
proc fetch_cert {save} {
|
|
global env vncdisplay is_windows
|
|
set hp [get_vncdisplay]
|
|
|
|
global vencrypt_detected
|
|
set vencrypt_detected ""
|
|
|
|
global use_listen
|
|
if {$use_listen} {
|
|
if {$is_windows} {
|
|
mesg "Fetch Cert not enabled for Reverse Connections"
|
|
bell
|
|
catch {raise .}
|
|
mac_raise
|
|
return
|
|
}
|
|
toplev .fcr
|
|
global help_font
|
|
wm title .fcr "Fetch Cert for Reverse Connections"
|
|
global fcr_result
|
|
set fcr_result 0
|
|
eval text .fcr.t -width 55 -height 17 $help_font
|
|
.fcr.t insert end {
|
|
In Reverse VNC Connections (-LISTEN) mode, the
|
|
Fetch Cert operation requires that the Remote
|
|
VNC Server makes an initial connection NOW so
|
|
we can collect its SSL Certificate. Note that
|
|
this method does not work for VeNCrypt servers.
|
|
(If there are problems Fetching, one can always
|
|
copy and import the Cert file manually.)
|
|
|
|
Do you want to Continue with this operation?
|
|
If so, press "Continue" and Then instruct the
|
|
remote VNC Server to make a Reverse Connection
|
|
to us.
|
|
|
|
Otherwise, press "Cancel" to cancel the Fetch
|
|
Cert operation.
|
|
}
|
|
|
|
button .fcr.cancel -text Cancel -command {set fcr_result 0; destroy .fcr}
|
|
button .fcr.continue -text Continue -command {set fcr_result 1; destroy .fcr}
|
|
button .fcr.continu2 -text Continue -command {set fcr_result 1; destroy .fcr}
|
|
global uname
|
|
if {$uname == "Darwin"} {
|
|
pack .fcr.t .fcr.continu2 .fcr.continue .fcr.cancel -side top -fill x
|
|
|
|
} else {
|
|
pack .fcr.t .fcr.continue .fcr.cancel -side top -fill x
|
|
}
|
|
center_win .fcr
|
|
|
|
tkwait window .fcr
|
|
update
|
|
after 50
|
|
|
|
if {$fcr_result != 1} {
|
|
return
|
|
}
|
|
update idletasks
|
|
after 50
|
|
}
|
|
|
|
regsub {[ ]*cmd=.*$} $hp "" tt
|
|
if {[regexp {^[ ]*$} $tt]} {
|
|
mesg "No host:disp supplied."
|
|
bell
|
|
catch {raise .}
|
|
mac_raise
|
|
return
|
|
}
|
|
if {[regexp -- {--nohost--} $tt]} {
|
|
mesg "No host:disp supplied."
|
|
bell
|
|
catch {raise .}
|
|
mac_raise
|
|
return
|
|
}
|
|
if {! [regexp ":" $hp]} {
|
|
if {! [regexp {cmd=} $hp]} {
|
|
append hp ":0"
|
|
}
|
|
}
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
|
|
|
|
set pstr 1
|
|
mesg "Fetching $hpnew Cert..."
|
|
global cert_text
|
|
set cert_text ""
|
|
.f4.getcert configure -state disabled
|
|
update
|
|
if {! $is_windows} {
|
|
catch {set cert_text [fetch_cert_unix $hp]}
|
|
} else {
|
|
set cert_text [fetch_cert_windows $hp]
|
|
}
|
|
|
|
if [info exists env(CERTDBG)] {puts "\nFetch-0-\n$cert_text"}
|
|
|
|
set vencrypt 0
|
|
set anondh 0
|
|
if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
|
|
if [regexp {CONNECTED} $cert_text] {
|
|
set m 0
|
|
if {![regexp -nocase {GET_SERVER_HELLO} $cert_text]} {
|
|
set m 1
|
|
}
|
|
if [regexp -nocase -line {GET_SERVER_HELLO.*unknown protocol} $cert_text] {
|
|
set m 1
|
|
}
|
|
if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} {
|
|
set m 1
|
|
}
|
|
if {!$m && $is_windows} {
|
|
if [regexp -nocase {write:errno} $cert_text] {
|
|
if [regexp -nocase {no peer certificate} $cert_text] {
|
|
set m 1
|
|
}
|
|
}
|
|
}
|
|
if {$m} {
|
|
# suspect VeNCrypt or ANONTLS plaintext RFB
|
|
set cert_text ""
|
|
set vencrypt 1
|
|
incr pstr
|
|
mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh"
|
|
if {! $is_windows} {
|
|
catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]}
|
|
} else {
|
|
after 600
|
|
catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]}
|
|
}
|
|
if [info exists env(CERTDBG)] {puts "\nFetch-1-\n$cert_text"}
|
|
}
|
|
}
|
|
}
|
|
if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
|
|
if [regexp {CONNECTED} $cert_text] {
|
|
set m 0
|
|
if [regexp -nocase -line {error.*handshake failure} $cert_text] {
|
|
set m 1
|
|
}
|
|
if [regexp -nocase -line {error.*unknown protocol} $cert_text] {
|
|
set m 1
|
|
}
|
|
if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} {
|
|
set m 1
|
|
}
|
|
if {!$m && $is_windows} {
|
|
if [regexp -nocase {no peer certificate} $cert_text] {
|
|
set m 1
|
|
}
|
|
}
|
|
if {$m} {
|
|
# suspect Anonymous Diffie Hellman
|
|
set cert_text ""
|
|
set anondh 1
|
|
incr pstr
|
|
mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh"
|
|
if {! $is_windows} {
|
|
catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]}
|
|
} else {
|
|
after 600
|
|
catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]}
|
|
}
|
|
if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"}
|
|
}
|
|
}
|
|
}
|
|
if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
|
|
if [regexp {CONNECTED} $cert_text] {
|
|
if {[regexp -nocase -line {cipher.*ADH} $cert_text]} {
|
|
# it is Anonymous Diffie Hellman
|
|
mesg "WARNING: Anonymous Diffie Hellman Server detected (NO CERT)"
|
|
after 300
|
|
.f4.getcert configure -state normal
|
|
return $cert_text
|
|
} else {
|
|
global vencrypt_detected
|
|
set vencrypt_detected ""
|
|
}
|
|
}
|
|
}
|
|
|
|
global vencrypt_detected server_vencrypt
|
|
if {$vencrypt_detected != "" && !$server_vencrypt} {
|
|
mesg "VeNCrypt or ANONTLS server detected."
|
|
after 600
|
|
}
|
|
|
|
.f4.getcert configure -state normal
|
|
mesg "Fetched $hpnew Cert"
|
|
|
|
set n 47
|
|
set ok 1
|
|
if {$cert_text == ""} {
|
|
set cert_text "An Error occurred in fetching SSL Certificate from $hp"
|
|
set ok 0
|
|
set n 4
|
|
} elseif {! [regexp {BEGIN CERTIFICATE} $cert_text]} {
|
|
set cert_text "An Error occurred in fetching $hp\n\n$cert_text"
|
|
set n [line_count $cert_text 1]
|
|
set ok 0
|
|
} else {
|
|
if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $cert_text] {
|
|
set new ""
|
|
set off 0
|
|
foreach line [split $cert_text "\n"] {
|
|
if [regexp -- {RFB 00} $line] {
|
|
continue
|
|
}
|
|
if [regexp -- {Using default temp} $line] {
|
|
continue
|
|
}
|
|
if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $line] {
|
|
set off 1
|
|
}
|
|
if [regexp -- {-----END SSL SESSION PARAMETERS-----} $line] {
|
|
set off 0
|
|
continue
|
|
}
|
|
if {$off} {
|
|
continue;
|
|
}
|
|
append new "$line\n"
|
|
}
|
|
if [regexp -- {-----BEGIN CERTIFICATE-----} $new] {
|
|
set cert_text $new
|
|
}
|
|
}
|
|
set text ""
|
|
set on 0
|
|
set subject ""
|
|
set curr_subject ""
|
|
set chain_n -1
|
|
set chain(__empty__) ""
|
|
foreach line [split $cert_text "\n"] {
|
|
if [regexp -- {-----BEGIN CERTIFICATE-----} $line] {
|
|
incr on
|
|
}
|
|
if {$chain_n < -1} {
|
|
;
|
|
} elseif [regexp {^ *([0-9]) *s:(.*/[A-Z][A-Z]*=.*$)} $line m cn sb] {
|
|
set cn [string trim $cn]
|
|
set sb [string trim $sb]
|
|
#puts cn=$cn
|
|
#puts sb=$sb
|
|
if {$subject == ""} {
|
|
set subject $sb
|
|
}
|
|
if {$cn > $chain_n} {
|
|
set chain_n $cn
|
|
set curr_subject $sb
|
|
} else {
|
|
set chain_n -2
|
|
}
|
|
} elseif [regexp {^ *i:(.*/[A-Z][A-Z]*=.*$)} $line m is] {
|
|
set is [string trim $is]
|
|
#puts is=$is
|
|
if {$curr_subject != ""} {
|
|
set chain($curr_subject) $is
|
|
}
|
|
}
|
|
if {$on != 1} {
|
|
continue;
|
|
}
|
|
append text "$line\n"
|
|
if [regexp -- {-----END CERTIFICATE-----} $line] {
|
|
set on 2
|
|
}
|
|
}
|
|
set chain_str "subject: not-known\n"
|
|
set curr_subject $subject
|
|
set self_signed 0
|
|
set top_issuer ""
|
|
for {set i 0} {$i < 10} {incr i} {
|
|
if {$curr_subject != ""} {
|
|
if {$i == 0} {
|
|
set chain_str "- subject: $curr_subject\n\n"
|
|
} else {
|
|
set chain_str "${chain_str}- issuer$i: $curr_subject\n\n"
|
|
set top_issuer $curr_subject;
|
|
}
|
|
if {![info exists chain($curr_subject)]} {
|
|
break
|
|
} elseif {$chain($curr_subject) == ""} {
|
|
break
|
|
} elseif {$curr_subject == $chain($curr_subject)} {
|
|
set j [expr $i + 1]
|
|
set chain_str "${chain_str}- issuer$j: $curr_subject\n\n"
|
|
set top_issuer $curr_subject;
|
|
if {$i == 0} {
|
|
set self_signed 1
|
|
}
|
|
break;
|
|
}
|
|
set curr_subject $chain($curr_subject)
|
|
}
|
|
}
|
|
set chain_str "${chain_str}INFO: SELF_SIGNED=$self_signed\n\n"
|
|
if {$self_signed} {
|
|
set chain_str "${chain_str}INFO: Certificate is Self-Signed.\n"
|
|
set chain_str "${chain_str}INFO: It will successfully authenticate when used as a ServerCert or Accepted-Cert.\n"
|
|
set chain_str "${chain_str}INFO: Be sure to check carefully that you trust this certificate before saving it.\n"
|
|
} else {
|
|
set chain_str "${chain_str}INFO: Certificate is signed by a Certificate Authority (CA).\n"
|
|
set chain_str "${chain_str}INFO: It *WILL NOT* successfully authenticate when used as a ServerCert or Accepted-Cert.\n"
|
|
set chain_str "${chain_str}INFO: You need to Obtain and Save the CA's Certificate (issuer) instead"
|
|
if {$top_issuer != ""} {
|
|
set chain_str "${chain_str}:\nINFO: CA: $top_issuer\n"
|
|
} else {
|
|
set chain_str "${chain_str}.\n"
|
|
}
|
|
}
|
|
#puts "\n$chain_str\n"
|
|
|
|
global is_windows
|
|
set tmp "/tmp/cert.hsh.[tpid]"
|
|
set tmp [mytmp $tmp]
|
|
if {$is_windows} {
|
|
# VF
|
|
set tmp cert.hsh
|
|
}
|
|
set fh ""
|
|
catch {set fh [open $tmp "w"]}
|
|
if {$fh != ""} {
|
|
puts $fh $text
|
|
close $fh
|
|
set info ""
|
|
catch {set info [get_x509_info $tmp]}
|
|
catch {file delete $tmp}
|
|
if [regexp -nocase {MD5 Finger[^\n]*} $info mvar] {
|
|
set cert_text "$mvar\n\n$cert_text"
|
|
}
|
|
if [regexp -nocase {SHA. Finger[^\n]*} $info mvar] {
|
|
set cert_text "$mvar\n\n$cert_text"
|
|
}
|
|
set cert_text "$cert_text\n\n----------------------------------\nOutput of openssl x509 -text -fingerprint:\n\n$info"
|
|
}
|
|
set cert_text "==== SSL Certificate from $hp ====\n\n$chain_str\n$cert_text"
|
|
}
|
|
|
|
if {! $save} {
|
|
return $cert_text
|
|
}
|
|
|
|
fetch_dialog $cert_text $hp $hpnew $ok $n
|
|
}
|
|
|
|
proc skip_non_self_signed {w hp} {
|
|
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?"
|
|
set reply [tk_messageBox -type okcancel -default cancel -parent $w -icon warning -message $msg -title "CA Signed Certificate"]
|
|
if {$reply == "cancel"} {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
proc fetch_dialog {cert_text hp hpnew ok n} {
|
|
toplev .fetch
|
|
|
|
if [small_height] {
|
|
set n 28
|
|
}
|
|
|
|
scroll_text_dismiss .fetch.f 90 $n
|
|
|
|
if {$ok} {
|
|
set ss 0
|
|
if [regexp {INFO: SELF_SIGNED=1} $cert_text] {
|
|
button .fetch.save -text Save -command "destroy .fetch; save_cert {$hpnew}"
|
|
set ss 1
|
|
} else {
|
|
button .fetch.save -text Save -command "if \[skip_non_self_signed .fetch {$hpnew}\] {return} else {destroy .fetch; save_cert {$hpnew}}"
|
|
set ss 0
|
|
}
|
|
button .fetch.help -text Help -command "help_fetch_cert $ss"
|
|
pack .fetch.help .fetch.save -side bottom -fill x
|
|
.fetch.d configure -text "Cancel"
|
|
}
|
|
|
|
center_win .fetch
|
|
wm title .fetch "$hp Certificate"
|
|
|
|
.fetch.f.t insert end $cert_text
|
|
jiggle_text .fetch.f.t
|
|
}
|
|
|
|
|
|
proc host_part {hp} {
|
|
regsub {^ *} $hp "" hp
|
|
regsub { .*$} $hp "" hp
|
|
if [regexp {^[0-9][0-9]*$} $hp] {
|
|
return ""
|
|
}
|
|
set h $hp
|
|
regsub {:[0-9][0-9]*$} $hp "" h
|
|
return $h
|
|
}
|
|
|
|
proc port_part {hp} {
|
|
regsub { .*$} $hp "" hp
|
|
set p ""
|
|
if [regexp {:([0-9][0-9]*)$} $hp m val] {
|
|
set p $val
|
|
}
|
|
return $p
|
|
}
|
|
|
|
proc get_vencrypt_proxy {hpnew} {
|
|
if [regexp -nocase {^vnc://} $hpnew] {
|
|
return ""
|
|
}
|
|
set hpnew [get_ssh_hp $hpnew]
|
|
regsub -nocase {^[a-z0-9+]*://} $hpnew "" hpnew
|
|
set h [host_part $hpnew]
|
|
set p [port_part $hpnew]
|
|
|
|
if {$p == ""} {
|
|
# might not matter, i.e. SSH+SSL only...
|
|
set p 5900
|
|
}
|
|
set hp2 $h
|
|
if {$p < 0} {
|
|
set hp2 "$hp2:[expr - $p]"
|
|
} elseif {$p < 200} {
|
|
set hp2 "$hp2:[expr $p + 5900]"
|
|
} else {
|
|
set hp2 "$hp2:$p"
|
|
}
|
|
return "vencrypt://$hp2"
|
|
}
|
|
|
|
proc fetch_cert_unix {hp {vencrypt 0} {anondh 0}} {
|
|
global use_listen
|
|
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
|
|
if {$vencrypt} {
|
|
global vencrypt_detected
|
|
set vencrypt_detected [get_vencrypt_proxy $hpnew]
|
|
if {$proxy != ""} {
|
|
set proxy "$proxy,$vencrypt_detected"
|
|
} else {
|
|
set proxy $vencrypt_detected
|
|
}
|
|
}
|
|
|
|
set cmd [list ss_vncviewer]
|
|
if {$anondh} {
|
|
lappend cmd "-anondh"
|
|
}
|
|
if {$proxy != ""} {
|
|
lappend cmd "-proxy"
|
|
lappend cmd $proxy
|
|
}
|
|
if {$use_listen} {
|
|
lappend cmd "-listen"
|
|
}
|
|
lappend cmd "-showcert"
|
|
lappend cmd $hpnew
|
|
|
|
if {$proxy != ""} {
|
|
lappend cmd "2>/dev/null"
|
|
}
|
|
global env
|
|
if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"}
|
|
set env(SSVNC_SHOWCERT_EXIT_0) 1
|
|
|
|
return [eval exec $cmd]
|
|
}
|
|
|
|
proc win_nslookup {host} {
|
|
global win_nslookup_cache
|
|
if [info exists win_nslookup_cache($host)] {
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
if [regexp -nocase {[^a-z0-9:._-]} $host] {
|
|
set win_nslookup_cache($host) "invalid"
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] {
|
|
set win_nslookup_cache($host) $host
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
if [regexp -nocase {^[a-f0-9]*:[a-f0-9:]*:[a-f0-9:]*$} $host] {
|
|
set win_nslookup_cache($host) $host
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
set nsout ""
|
|
catch {set nsout [exec nslookup $host]}
|
|
if {$nsout == "" || [regexp -nocase {server failed} $nsout]} {
|
|
after 250
|
|
set nsout ""
|
|
catch {set nsout [exec nslookup $host]}
|
|
}
|
|
if {$nsout == "" || [regexp -nocase {server failed} $nsout]} {
|
|
set win_nslookup_cache($host) "unknown"
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
regsub -all {Server:[^\n]*\nAddress:[^\n]*} $nsout "" nsout
|
|
regsub {^.*Name:} $nsout "" nsout
|
|
if [regexp {Address:[ \t]*([^\n]+)} $nsout mv addr] {
|
|
set addr [string trim $addr]
|
|
if {$addr != ""} {
|
|
set win_nslookup_cache($host) $addr
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
}
|
|
set win_nslookup_cache($host) "unknown"
|
|
return $win_nslookup_cache($host)
|
|
}
|
|
|
|
proc win_ipv4 {host} {
|
|
global win_localhost
|
|
set ip [win_nslookup $host];
|
|
if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $ip] {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc ipv6_proxy {proxy host port} {
|
|
global is_windows win_localhost have_ipv6
|
|
|
|
if {!$have_ipv6} {
|
|
return [list $proxy $host $port ""]
|
|
} elseif {!$is_windows} {
|
|
return [list $proxy $host $port ""]
|
|
} else {
|
|
set h0 ""
|
|
set p0 ""
|
|
set port3 ""
|
|
set ipv6_pid ""
|
|
set proxy0 $proxy
|
|
if {$proxy == ""} {
|
|
if [win_ipv4 $host] {
|
|
return [list $proxy $host $port ""]
|
|
}
|
|
set port3 [rand_port]
|
|
set h0 $host
|
|
set p0 $port
|
|
set host $win_localhost
|
|
set port $port3
|
|
} else {
|
|
set parts [split $proxy ","]
|
|
set n [llength $parts]
|
|
for {set i 0} {$i < $n} {incr i} {
|
|
set part [lindex $parts $i]
|
|
set prefix ""
|
|
set repeater 0
|
|
regexp -nocase {^[a-z0-9+]*://} $part prefix
|
|
regsub -nocase {^[a-z0-9+]*://} $part "" part
|
|
if [regexp {^repeater://} $prefix] {
|
|
regsub {\+.*$} $part "" part
|
|
if {![regexp {:([0-9][0-9]*)$} $part]} {
|
|
set part "$part:5900"
|
|
}
|
|
}
|
|
set modit 0
|
|
set h1 ""
|
|
set p1 ""
|
|
if [regexp {^(.*):([0-9][0-9]*)$} $part mvar h1 p1] {
|
|
if {$h1 == "localhost" || $h1 == $win_localhost} {
|
|
continue
|
|
} elseif [win_ipv4 $h1] {
|
|
break
|
|
}
|
|
set modit 1
|
|
} else {
|
|
break
|
|
}
|
|
if {$modit} {
|
|
set port3 [rand_port]
|
|
set h0 $h1
|
|
set p0 $p1
|
|
lset parts $i "$prefix$win_localhost:$port3"
|
|
break
|
|
}
|
|
}
|
|
if {$h0 != "" && $p0 != "" && $port3 != ""} {
|
|
set proxy [join $parts ","]
|
|
#mesg "Reset proxy: $proxy"; after 3000
|
|
}
|
|
}
|
|
if {$h0 != "" && $p0 != "" && $port3 != ""} {
|
|
mesg "Starting IPV6 helper on port $port3 ..."
|
|
set ipv6_pid [exec relay6.exe $port3 "$h0" "$p0" /b:$win_localhost &]
|
|
after 400
|
|
#mesg "r6 $port3 $h0 $p0"; after 3000
|
|
}
|
|
return [list $proxy $host $port $ipv6_pid]
|
|
}
|
|
}
|
|
|
|
proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} {
|
|
global have_ipv6
|
|
|
|
regsub {^vnc.*://} $hp "" hp
|
|
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
|
|
if {$vencrypt} {
|
|
global vencrypt_detected
|
|
set vencrypt_detected [get_vencrypt_proxy $hpnew]
|
|
if {$proxy != ""} {
|
|
set proxy "$proxy,$vencrypt_detected"
|
|
} else {
|
|
set proxy $vencrypt_detected
|
|
}
|
|
}
|
|
|
|
set host [host_part $hpnew]
|
|
|
|
global win_localhost
|
|
|
|
if {$host == ""} {
|
|
set host $win_localhost
|
|
}
|
|
|
|
if [regexp {^.*@} $host match] {
|
|
mesg "Trimming \"$match\" from hostname"
|
|
regsub {^.*@} $host "" host
|
|
}
|
|
|
|
set disp [port_part $hpnew]
|
|
|
|
if {[regexp {^-[0-9][0-9]*$} $disp]} {
|
|
;
|
|
} elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
|
|
set disp 0
|
|
}
|
|
if {$disp < 0} {
|
|
set port [expr "- $disp"]
|
|
} elseif {$disp < 200} {
|
|
set port [expr "$disp + 5900"]
|
|
} else {
|
|
set port $disp
|
|
}
|
|
|
|
set ipv6_pid ""
|
|
if {$have_ipv6} {
|
|
set res [ipv6_proxy $proxy $host $port]
|
|
set proxy [lindex $res 0]
|
|
set host [lindex $res 1]
|
|
set port [lindex $res 2]
|
|
set ipv6_pid [lindex $res 3]
|
|
}
|
|
|
|
if {$proxy != ""} {
|
|
global env
|
|
|
|
set port2 [rand_port]
|
|
|
|
set sp ""
|
|
if [info exists env(SSVNC_PROXY)] {
|
|
set sp $env(SSVNC_PROXY)
|
|
}
|
|
set sl ""
|
|
if [info exists env(SSVNC_LISTEN)] {
|
|
set sl $env(SSVNC_LISTEN)
|
|
}
|
|
set sd ""
|
|
if [info exists env(SSVNC_DEST)] {
|
|
set sd $env(SSVNC_DEST)
|
|
}
|
|
|
|
set env(SSVNC_PROXY) $proxy
|
|
set env(SSVNC_LISTEN) $port2
|
|
set env(SSVNC_DEST) "$host:$port"
|
|
|
|
set host $win_localhost
|
|
set port $port2
|
|
|
|
mesg "Starting Proxy TCP helper on port $port2 ..."
|
|
after 300
|
|
# fetch cert br case:
|
|
set proxy_pid [exec "connect_br.exe" &]
|
|
|
|
if {$sp == ""} {
|
|
catch { unset env(SSVNC_PROXY) }
|
|
} else {
|
|
set env(SSVNC_PROXY) $sp
|
|
}
|
|
if {$sl == ""} {
|
|
catch { unset env(SSVNC_LISTEN) }
|
|
} else {
|
|
set env(SSVNC_LISTEN) $sl
|
|
}
|
|
if {$sd == ""} {
|
|
catch { unset env(SSVNC_DEST) }
|
|
} else {
|
|
set env(SSVNC_DEST) $sd
|
|
}
|
|
}
|
|
|
|
set ossl [get_openssl]
|
|
update
|
|
# VF
|
|
set tin tmpin.txt
|
|
set tou tmpout.txt
|
|
set fh ""
|
|
catch {set fh [open $tin "w"]}
|
|
if {$fh != ""} {
|
|
puts $fh "Q"
|
|
puts $fh "GET /WOMBAT HTTP/1.1\r\nHost: wombat.com\r\n\r\n\r\n"
|
|
close $fh
|
|
}
|
|
|
|
if {1} {
|
|
set ph ""
|
|
if {$anondh} {
|
|
set ph [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin 2>NUL" "r"]
|
|
} else {
|
|
set ph [open "| $ossl s_client -prexit -connect $host:$port < $tin 2>NUL" "r"]
|
|
}
|
|
|
|
set text ""
|
|
if {$ph != ""} {
|
|
set pids [pid $ph]
|
|
set got 0
|
|
while {[gets $ph line] > -1} {
|
|
append text "$line\n"
|
|
if [regexp {END CERT} $line] {
|
|
set got 1
|
|
}
|
|
if {$anondh && [regexp -nocase {cipher.*ADH} $line]} {
|
|
set got 1
|
|
}
|
|
if {$got && [regexp {^ *Verify return code} $line]} {
|
|
break
|
|
}
|
|
if [regexp {^RFB } $line] {
|
|
break
|
|
}
|
|
if [regexp {^DONE} $line] {
|
|
break
|
|
}
|
|
}
|
|
foreach pid $pids {
|
|
winkill $pid
|
|
}
|
|
if {$ipv6_pid != ""} {
|
|
winkill $ipv6_pid
|
|
}
|
|
|
|
catch {close $ph}
|
|
catch {file delete $tin $tou}
|
|
return $text
|
|
}
|
|
} else {
|
|
set pids ""
|
|
|
|
if {1} {
|
|
if {$anondh} {
|
|
set ph2 [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH > $tou 2>NUL" "w"]
|
|
} else {
|
|
set ph2 [open "| $ossl s_client -prexit -connect $host:$port > $tou 2>NUL" "w"]
|
|
}
|
|
set pids [pid $ph2]
|
|
after 500
|
|
for {set i 0} {$i < 128} {incr i} {
|
|
puts $ph2 "Q"
|
|
}
|
|
catch {close $ph2}
|
|
} else {
|
|
if {$anondh} {
|
|
set pids [exec $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin >& $tou &]
|
|
} else {
|
|
set pids [exec $ossl s_client -prexit -connect $host:$port < $tin >& $tou &]
|
|
}
|
|
}
|
|
|
|
for {set i 0} {$i < 10} {incr i} {
|
|
after 500
|
|
set got 0
|
|
set ph ""
|
|
catch {set ph [open $tou "r"]}
|
|
if {$ph != ""} {
|
|
while {[gets $ph line] > -1} {
|
|
if [regexp {END CERT} $line] {
|
|
set got 1
|
|
break
|
|
}
|
|
}
|
|
close $ph
|
|
}
|
|
if {$got} {
|
|
break
|
|
}
|
|
}
|
|
foreach pid $pids {
|
|
winkill $pid
|
|
}
|
|
after 500
|
|
set ph ""
|
|
catch {set ph [open $tou "r"]}
|
|
}
|
|
set text ""
|
|
if {$ph != ""} {
|
|
while {[gets $ph line] > -1} {
|
|
append text "$line\n"
|
|
}
|
|
close $ph
|
|
}
|
|
catch {file delete $tin $tou}
|
|
if {$ipv6_pid != ""} {
|
|
winkill $ipv6_pid
|
|
}
|
|
return $text
|
|
}
|
|
|
|
proc check_accepted_certs {{probe_only 0}} {
|
|
global cert_text always_verify_ssl
|
|
global skip_verify_accepted_certs use_listen
|
|
global ultra_dsm env
|
|
global server_vencrypt server_anondh no_probe_vencrypt
|
|
|
|
if {! $always_verify_ssl} {
|
|
set skip_verify_accepted_certs 1
|
|
if {$server_vencrypt} {
|
|
return 1
|
|
}
|
|
if {$no_probe_vencrypt} {
|
|
return 1
|
|
}
|
|
}
|
|
if {$server_anondh} {
|
|
mesg "WARNING: Anonymous Diffie Hellman (SKIPPING CERT CHECK)"
|
|
after 1000
|
|
set skip_verify_accepted_certs 1
|
|
return 1
|
|
}
|
|
if {$ultra_dsm} {
|
|
return 1;
|
|
}
|
|
if {$use_listen} {
|
|
return 1;
|
|
}
|
|
|
|
global anon_dh_detected
|
|
set anon_dh_detected 0
|
|
|
|
set cert_text [fetch_cert 0]
|
|
|
|
set mvar ""
|
|
if {[regexp -nocase -line {cipher.*ADH} $cert_text mvar]} {
|
|
|
|
if [info exists env(CERTDBG)] {puts "\nFetch-MSG-\n$cert_text"}
|
|
if [info exists env(CERTDBG)] {puts "\nBEGIN_MVAR: $mvar\nEND_MVAR\n"}
|
|
|
|
set msg "Anonymous Diffie-Hellman server detected. There will be encryption, but no SSL/TLS authentication. Continue?"
|
|
set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title "Anonymous Diffie-Hellman Detected"]
|
|
set anon_dh_detected 1
|
|
if {$reply == "cancel"} {
|
|
return 0
|
|
} else {
|
|
global skip_verify_accepted_certs
|
|
set skip_verify_accepted_certs 1
|
|
return 1
|
|
}
|
|
}
|
|
|
|
if {$probe_only} {
|
|
return 1
|
|
}
|
|
if {! $always_verify_ssl} {
|
|
return 1
|
|
}
|
|
|
|
set from ""
|
|
set fingerprint ""
|
|
set fingerline ""
|
|
set self_signed 1
|
|
set subject_issuer ""
|
|
set subject ""
|
|
set issuer ""
|
|
|
|
set i 0
|
|
foreach line [split $cert_text "\n"] {
|
|
incr i
|
|
if {$i > 50} {
|
|
break
|
|
}
|
|
if [regexp {^- subject: *(.*)$} $line m val] {
|
|
set val [string trim $val]
|
|
set subject_issuer "${subject_issuer}subject:$val\n"
|
|
set subject $val
|
|
}
|
|
if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] {
|
|
set val [string trim $val]
|
|
set subject_issuer "${subject_issuer}$is:$val\n"
|
|
set issuer $val
|
|
}
|
|
if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] {
|
|
set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n"
|
|
}
|
|
if [regexp {^depth=} $line] {
|
|
break
|
|
}
|
|
if [regexp {^verify } $line] {
|
|
break
|
|
}
|
|
if [regexp {^CONNECTED} $line] {
|
|
break
|
|
}
|
|
if [regexp {^Certificate chain} $line] {
|
|
break
|
|
}
|
|
if [regexp {^==== SSL Certificate from (.*) ====} $line mv str] {
|
|
set from [string trim $str]
|
|
}
|
|
if [regexp -nocase {Fingerprint=(.*)} $line mv str] {
|
|
set fingerline $line
|
|
set fingerprint [string trim $str]
|
|
}
|
|
if [regexp -nocase {^INFO: SELF_SIGNED=([01])} $line mv str] {
|
|
set self_signed $str
|
|
}
|
|
}
|
|
|
|
set fingerprint [string tolower $fingerprint]
|
|
regsub -all {:} $fingerprint "-" fingerprint
|
|
regsub -all {[\\/=]} $fingerprint "_" fingerprint
|
|
|
|
set from [string tolower $from]
|
|
regsub -all {[\[\]]} $from "" from
|
|
regsub -all {^[+a-z]*://} $from "" from
|
|
regsub -all {:} $from "-" from
|
|
regsub -all {[\\/=]} $from "_" from
|
|
regsub -all {[ ]} $from "_" from
|
|
|
|
if {$from == "" || $fingerprint == ""} {
|
|
bell
|
|
catch {raise .; update}
|
|
mesg "WARNING: Error fetching Server Cert"
|
|
after 500
|
|
set hp [get_vncdisplay]
|
|
set n [line_count $cert_text 1]
|
|
fetch_dialog $cert_text $hp $hp 0 $n
|
|
update
|
|
after 2000
|
|
return 0
|
|
}
|
|
|
|
set hp [get_vncdisplay]
|
|
|
|
set adir [get_idir_certs ""]
|
|
catch {file mkdir $adir}
|
|
set adir "$adir/accepted"
|
|
catch {file mkdir $adir}
|
|
|
|
set crt "$adir/$from=$fingerprint.crt"
|
|
|
|
if [file exists $crt] {
|
|
if {$self_signed} {
|
|
mesg "OK: Certificate found in ACCEPTED_CERTS"
|
|
after 750
|
|
return 1
|
|
}
|
|
}
|
|
|
|
set cnt 0
|
|
foreach f [glob -nocomplain -directory $adir "*$fingerprint*.crt"] {
|
|
mesg "CERT: $f"
|
|
after 150
|
|
if {$self_signed} {
|
|
incr cnt
|
|
}
|
|
}
|
|
|
|
set oth 0
|
|
set others [list]
|
|
foreach f [glob -nocomplain -directory $adir "*$from*.crt"] {
|
|
if {$f == $crt} {
|
|
continue
|
|
}
|
|
set fb [file tail $f]
|
|
mesg "OTHER CERT: $fb"
|
|
if {$cnt > 0} {
|
|
after 400
|
|
} else {
|
|
bell
|
|
after 800
|
|
}
|
|
lappend others $f
|
|
incr oth
|
|
}
|
|
|
|
foreach f [glob -nocomplain -directory $adir "*.crt"] {
|
|
if {$f == $crt} {
|
|
continue
|
|
}
|
|
set saw 0
|
|
foreach o $others {
|
|
if {$f == $o} {
|
|
set saw 1
|
|
break
|
|
}
|
|
}
|
|
if {$saw} {
|
|
continue
|
|
}
|
|
set fh [open $f "r"]
|
|
if {$fh == ""} {
|
|
continue
|
|
}
|
|
set same 0
|
|
set sub ""
|
|
set iss ""
|
|
set isn -1;
|
|
while {[gets $fh line] > -1} {
|
|
if [regexp {^Host-Display: (.*)$} $line mv hd] {
|
|
if {$hd == $hp || $hd == $from} {
|
|
set same 1
|
|
}
|
|
}
|
|
if [regexp {^subject:(.*)$} $line mv val] {
|
|
set sub $val
|
|
}
|
|
if [regexp {^issue([0-9][0-9]*):(.*)$} $line mv in val] {
|
|
if {$in > $isn} {
|
|
set isn $in
|
|
set iss $val
|
|
}
|
|
}
|
|
}
|
|
close $fh;
|
|
|
|
if {!$self_signed} {
|
|
if {$sub == ""} {
|
|
set ossl [get_openssl]
|
|
set si_txt [exec $ossl x509 -subject -issuer -noout -in $f]
|
|
foreach line [split $si_txt "\n"] {
|
|
if [regexp -nocase {^subject= *(.*)$} $line mv str] {
|
|
set str [string trim $str]
|
|
if {$str != ""} {
|
|
set sub $str
|
|
}
|
|
} elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] {
|
|
set str [string trim $str]
|
|
if {$iss != ""} {
|
|
set iss $str
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if {$issuer != "" && $sub != ""} {
|
|
global env
|
|
if [info exists env(CERTDBG)] {
|
|
puts "f: $f"
|
|
puts "s: $sub"
|
|
puts "i: $issuer"
|
|
puts "==================="
|
|
}
|
|
if {$issuer == $sub} {
|
|
set fb [file tail $f]
|
|
mesg "Certificate Authority (CA) CERT: $fb"
|
|
incr cnt
|
|
after 500
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
|
|
if {! $same} {
|
|
continue
|
|
}
|
|
|
|
set fb [file tail $f]
|
|
mesg "OTHER CERT: $fb"
|
|
if {$cnt > 0} {
|
|
after 400
|
|
} else {
|
|
bell
|
|
after 800
|
|
}
|
|
lappend others $f
|
|
incr oth
|
|
}
|
|
|
|
if {$cnt > 0} {
|
|
if {$self_signed} {
|
|
mesg "OK: Server Certificate found in ACCEPTED_CERTS"
|
|
after 400
|
|
} else {
|
|
mesg "OK: CA Certificate found in ACCEPTED_CERTS"
|
|
after 800
|
|
}
|
|
return 1
|
|
}
|
|
|
|
set hp2 [get_vncdisplay]
|
|
set msg "
|
|
The Self-Signed SSL Certificate from host:
|
|
|
|
$hp2
|
|
|
|
Fingerprint: $fingerprint
|
|
|
|
Subject: $subject
|
|
|
|
is not present in the 'Accepted Certs' directory:
|
|
|
|
$adir
|
|
%WARN
|
|
You will need to verify on your own that this is a certificate from a
|
|
VNC server that you trust (e.g. by checking the fingerprint with that
|
|
sent to you by the server administrator).
|
|
|
|
|
|
THE QUESTION: Do you want this certificate to be saved in the Accepted Certs
|
|
directory and then used to SSL authenticate VNC servers?
|
|
|
|
|
|
By clicking 'Inspect and maybe Save Cert' you will be given the opportunity
|
|
to inspect the certificate before deciding to save it or not.
|
|
"
|
|
|
|
set msg_bottom "
|
|
Choose 'Ignore Cert for One Connection' to connect a single time to the
|
|
server with *NO* certificate authentication. You will see this dialog again
|
|
the next time you connect to the same server.
|
|
|
|
Choose 'Continue as though I saved it' to launch stunnel and the VNC viewer.
|
|
Do this if you know the correct Certificate is in the 'Accepted Certs'
|
|
directory. If it is not, stunnel will fail and report 'VERIFY ERROR:...'
|
|
|
|
Choose 'Cancel' to not connect to the VNC Server at all.
|
|
"
|
|
|
|
set msg_ca "
|
|
The CA-signed SSL Certificate from host:
|
|
|
|
$hp2
|
|
|
|
Fingerprint: $fingerprint
|
|
|
|
Subject: $subject
|
|
|
|
Issuer: $issuer
|
|
|
|
is signed by a Certificate Authority (CA) (the 'Issuer' above.)
|
|
|
|
However, the certificate of the CA 'Issuer' is not present in the
|
|
'Accepted Certs' directory:
|
|
|
|
$adir
|
|
|
|
You will need to obtain the certificate of the CA 'Issuer' via some means
|
|
(perhaps ask the VNC server administrator for it.) Then, after you have
|
|
verified that the CA certificate is one that you trust, import the
|
|
certificate via Certs -> Import Certificate. Be sure to select to also
|
|
save it to the Accepted Certs directory so it will automatically be used.
|
|
"
|
|
set msg "$msg$msg_bottom"
|
|
set msg_ca "$msg_ca$msg_bottom"
|
|
|
|
if {!$self_signed} {
|
|
set msg $msg_ca
|
|
}
|
|
|
|
if {$oth == 0} {
|
|
regsub {%WARN} $msg "" msg
|
|
} else {
|
|
set warn ""
|
|
set wfp ""
|
|
if {$oth == 1} {
|
|
set warn "
|
|
**WARNING** The Following Cert was previously saved FOR THE SAME HOST-DISPLAY:
|
|
|
|
"
|
|
set wfp "BUT WITH A DIFFERENT FINGERPRINT."
|
|
|
|
} else {
|
|
set warn "
|
|
**WARNING** The Following Certs were previously saved FOR THE SAME HOST-DISPLAY:
|
|
|
|
"
|
|
set wfp "BUT WITH DIFFERENT FINGERPRINTS."
|
|
}
|
|
|
|
foreach o $others {
|
|
set fb [file tail $o]
|
|
set warn "$warn $fb\n"
|
|
}
|
|
set warn "$warn\n $wfp\n"
|
|
set warn "$warn\n This could be a Man-In-The-Middle attack, or simply that the Server changed"
|
|
set warn "$warn\n its Certificate. *PLEASE CHECK* before proceeding!\n"
|
|
regsub {%WARN} $msg $warn msg
|
|
bell
|
|
}
|
|
|
|
set n 0
|
|
foreach l [split $msg "\n"] {
|
|
incr n
|
|
}
|
|
if {!$self_signed} {
|
|
set n [expr $n + 2]
|
|
} else {
|
|
set n [expr $n + 1]
|
|
}
|
|
if [small_height] {
|
|
if {$n > 26} {
|
|
set n 26
|
|
}
|
|
}
|
|
toplev .acert
|
|
scroll_text .acert.f 83 $n
|
|
|
|
button .acert.inspect -text "Inspect and maybe Save Cert ..." -command "destroy .acert; set accept_cert_dialog 1"
|
|
button .acert.accept -text "Ignore Cert for One Connection " -command "destroy .acert; set accept_cert_dialog 2"
|
|
button .acert.continue -text "Continue as though I saved it " -command "destroy .acert; set accept_cert_dialog 3"
|
|
button .acert.cancel -text "Cancel" -command "destroy .acert; set accept_cert_dialog 0"
|
|
|
|
wm title .acert "Unrecognized SSL Cert!"
|
|
|
|
.acert.f.t insert end $msg
|
|
|
|
pack .acert.cancel .acert.continue .acert.accept .acert.inspect -side bottom -fill x
|
|
pack .acert.f -side top -fill both -expand 1
|
|
|
|
if {! $self_signed} {
|
|
catch {.acert.inspect configure -state disabled}
|
|
}
|
|
|
|
center_win .acert
|
|
|
|
global accept_cert_dialog
|
|
set accept_cert_dialog ""
|
|
|
|
jiggle_text .acert.f.t
|
|
|
|
tkwait window .acert
|
|
|
|
if {$accept_cert_dialog == 2} {
|
|
set skip_verify_accepted_certs 1
|
|
return 1
|
|
}
|
|
if {$accept_cert_dialog == 3} {
|
|
return 1
|
|
}
|
|
if {$accept_cert_dialog != 1} {
|
|
return 0
|
|
}
|
|
|
|
global accepted_cert_dialog_in_progress
|
|
set accepted_cert_dialog_in_progress 1
|
|
|
|
global fetch_cert_filename
|
|
set fetch_cert_filename $crt
|
|
|
|
global do_save_saved_it
|
|
set do_save_saved_it 0
|
|
global do_save_saved_hash_it
|
|
set do_save_saved_hash_it 0
|
|
|
|
fetch_dialog $cert_text $hp $hp 1 47
|
|
update; after 150
|
|
|
|
catch {tkwait window .fetch}
|
|
update; after 250
|
|
catch {tkwait window .scrt}
|
|
update; after 250
|
|
if [winfo exists .scrt] {
|
|
catch {tkwait window .scrt}
|
|
}
|
|
|
|
set fetch_cert_filename ""
|
|
set accepted_cert_dialog_in_progress 0
|
|
|
|
if {!$do_save_saved_hash_it} {
|
|
save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer
|
|
}
|
|
|
|
if {$do_save_saved_it} {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
proc save_hash {crt adir hp fingerline from fingerprint {subject_issuer ""}} {
|
|
if ![file exists $crt] {
|
|
return
|
|
}
|
|
set ossl [get_openssl]
|
|
set hash [exec $ossl x509 -hash -noout -in $crt]
|
|
set hash [string trim $hash]
|
|
if [regexp {^([0-9a-f][0-9a-f]*)} $hash mv h] {
|
|
set hashfile "$adir/$h.0"
|
|
set hn "$h.0"
|
|
if [file exists $hashfile] {
|
|
set hashfile "$adir/$h.1"
|
|
set hn "$h.1"
|
|
if [file exists $hashfile] {
|
|
set hashfile "$adir/$h.2"
|
|
set hn "$h.2"
|
|
}
|
|
}
|
|
set fh [open $crt "a"]
|
|
if {$fh != ""} {
|
|
puts $fh ""
|
|
puts $fh "SSVNC-info:"
|
|
puts $fh "Host-Display: $hp"
|
|
puts $fh "$fingerline"
|
|
puts $fh "hash-filename: $hn"
|
|
puts $fh "full-filename: $from=$fingerprint.crt"
|
|
puts -nonewline $fh $subject_issuer
|
|
close $fh
|
|
}
|
|
catch {file copy -force $crt $hashfile}
|
|
if [file exists $hashfile] {
|
|
return 1
|
|
}
|
|
}
|
|
}
|
|
|
|
proc tpid {} {
|
|
global is_windows
|
|
set p ""
|
|
|
|
if {!$is_windows} {
|
|
catch {set p [exec sh -c {echo $$}]}
|
|
}
|
|
if {$p == ""} {
|
|
set p [pid];
|
|
}
|
|
append p [clock clicks]
|
|
return $p
|
|
}
|
|
|
|
proc repeater_proxy_check {proxy} {
|
|
if [regexp {^repeater://.*\+ID:[0-9]} $proxy] {
|
|
global env rpc_m1 rpc_m2
|
|
if {![info exists rpc_m1]} {
|
|
set rpc_m1 0
|
|
set rpc_m2 0
|
|
}
|
|
set force 0
|
|
if [info exists env(REPEATER_FORCE)] {
|
|
if {$env(REPEATER_FORCE) != "" && $env(REPEATER_FORCE) != "0"} {
|
|
# no longer makes a difference.
|
|
set force 1
|
|
}
|
|
}
|
|
global use_listen ultra_dsm
|
|
if {! $use_listen} {
|
|
if {$ultra_dsm} {
|
|
return 1;
|
|
} else {
|
|
if {0} {
|
|
mesg "WARNING: repeater:// ID:nnn proxy might need Listen Mode"
|
|
incr rpc_m1
|
|
if {$rpc_m1 <= 2} {
|
|
after 1000
|
|
} else {
|
|
after 200
|
|
}
|
|
}
|
|
if {0} {
|
|
# no longer required by x11vnc (X11VNC_DISABLE_SSL_CLIENT_MODE)
|
|
bell
|
|
mesg "ERROR: repeater:// ID:nnn proxy must use Listen Mode"
|
|
after 1000
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
global always_verify_ssl
|
|
if [info exists always_verify_ssl] {
|
|
if {$always_verify_ssl} {
|
|
mesg "WARNING: repeater:// ID:nnn Verify All Certs may fail"
|
|
incr rpc_m2
|
|
if {$rpc_m2 == 1} {
|
|
after 1500
|
|
} elseif {$rpc_m2 == 2} {
|
|
after 500
|
|
} else {
|
|
after 200
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 1
|
|
}
|
|
|
|
proc fini_unixpw {} {
|
|
global named_pipe_fh unixpw_tmp
|
|
|
|
if {$named_pipe_fh != ""} {
|
|
catch {close $named_pipe_fh}
|
|
}
|
|
if {$unixpw_tmp != ""} {
|
|
catch {file delete $unixpw_tmp}
|
|
}
|
|
}
|
|
|
|
proc init_unixpw {hp} {
|
|
global use_unixpw unixpw_username unixpw_passwd
|
|
global named_pipe_fh unixpw_tmp env
|
|
|
|
set named_pipe_fh ""
|
|
set unixpw_tmp ""
|
|
|
|
if {$use_unixpw} {
|
|
set name $unixpw_username
|
|
set env(SSVNC_UNIXPW) ""
|
|
if {$name == ""} {
|
|
regsub {^.*://} $hp "" hp
|
|
set hptmp [get_ssh_hp $hp]
|
|
if [regexp {^(.*)@} $hptmp mv m1] {
|
|
set name $m1
|
|
}
|
|
}
|
|
if {$name == ""} {
|
|
if [info exists env(USER)] {
|
|
set name $env(USER)
|
|
}
|
|
}
|
|
if {$name == ""} {
|
|
if [info exists env(LOGNAME)] {
|
|
set name $env(LOGNAME)
|
|
}
|
|
}
|
|
if {$name == ""} {
|
|
set name [exec whoami]
|
|
}
|
|
if {$name == ""} {
|
|
set name "unknown"
|
|
}
|
|
|
|
set tmp "/tmp/unixpipe.[tpid]"
|
|
set tmp [mytmp $tmp]
|
|
# need to make it a pipe
|
|
catch {file delete $tmp}
|
|
if {[file exists $tmp]} {
|
|
mesg "file still exists: $tmp"
|
|
bell
|
|
return
|
|
}
|
|
|
|
catch {exec mknod $tmp p}
|
|
set fh ""
|
|
if {! [file exists $tmp]} {
|
|
catch {set fh [open $tmp "w"]}
|
|
} else {
|
|
catch {set fh [open $tmp "r+"]}
|
|
set named_pipe_fh $fh
|
|
}
|
|
catch {exec chmod 600 $tmp}
|
|
if {! [file exists $tmp]} {
|
|
mesg "cannot create: $tmp"
|
|
if {$named_pipe_fh != ""} {catch close $named_pipe_fh}
|
|
bell
|
|
return
|
|
}
|
|
#puts [exec ls -l $tmp]
|
|
set unixpw_tmp $tmp
|
|
puts $fh $name
|
|
puts $fh $unixpw_passwd
|
|
if {$named_pipe_fh != ""} {
|
|
flush $fh
|
|
} else {
|
|
close $fh
|
|
}
|
|
exec sh -c "sleep 60; /bin/rm -f $tmp" &
|
|
if {$unixpw_passwd == ""} {
|
|
set env(SSVNC_UNIXPW) "."
|
|
} else {
|
|
set env(SSVNC_UNIXPW) "rm:$tmp"
|
|
}
|
|
} else {
|
|
if [info exists env(SSVNC_UNIXPW)] {
|
|
set env(SSVNC_UNIXPW) ""
|
|
}
|
|
}
|
|
}
|
|
|
|
proc check_for_listen_ssl_cert {} {
|
|
global mycert use_listen use_ssh ultra_dsm
|
|
if {! $use_listen} {
|
|
return 1
|
|
}
|
|
if {$use_ssh} {
|
|
return 1
|
|
}
|
|
if {$ultra_dsm} {
|
|
return 1
|
|
}
|
|
if {$mycert != ""} {
|
|
return 1
|
|
}
|
|
|
|
set name [get_idir_certs ""]
|
|
set name "$name/listen.pem"
|
|
if {[file exists $name]} {
|
|
set mycert $name
|
|
mesg "Using Listen Cert: $name"
|
|
after 700
|
|
return 1
|
|
}
|
|
|
|
set title "SSL Listen requires MyCert";
|
|
set msg "In SSL Listen mode a cert+key is required, but you have not specified 'MyCert'.\n\nCreate a cert+key 'listen' now?"
|
|
set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title $msg]
|
|
if {$reply == "cancel"} {
|
|
return 0
|
|
}
|
|
create_cert $name
|
|
tkwait window .ccrt
|
|
if {[file exists $name]} {
|
|
set mycert $name
|
|
mesg "Using Listen Cert: $name"
|
|
after 700
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc listen_verify_all_dialog {hp} {
|
|
global use_listen always_verify_ssl
|
|
global did_listen_verify_all_dialog
|
|
global svcert
|
|
global sshssl_sw ultra_dsm
|
|
|
|
if {!$use_listen} {
|
|
return 1
|
|
}
|
|
if {!$always_verify_ssl} {
|
|
return 1
|
|
}
|
|
if {$svcert != ""} {
|
|
return 1
|
|
}
|
|
if {$ultra_dsm} {
|
|
return 1
|
|
}
|
|
if [regexp -nocase {^vnc://} $hp] {
|
|
return 1
|
|
}
|
|
if [info exists sshssl_sw] {
|
|
if {$sshssl_sw == "none"} {
|
|
return 1
|
|
}
|
|
if {$sshssl_sw == "ssh"} {
|
|
return 1
|
|
}
|
|
}
|
|
if [info exists did_listen_verify_all_dialog] {
|
|
return 1
|
|
}
|
|
|
|
toplev .lvd
|
|
global help_font
|
|
wm title .lvd "Verify All Certs for Reverse Connections"
|
|
eval text .lvd.t -width 55 -height 22 $help_font
|
|
.lvd.t insert end {
|
|
Information:
|
|
|
|
You have the 'Verify All Certs' option enabled
|
|
in Reverse VNC Connections (-LISTEN) mode.
|
|
|
|
For this to work, you must have ALREADY saved
|
|
the remote VNC Server's Certificate to the
|
|
'Accepted Certs' directory. Otherwise the
|
|
incoming Reverse connection will be rejected.
|
|
|
|
You can save the Server's Certificate by using
|
|
the 'Import Certificate' dialog or on Unix
|
|
and MacOSX by pressing 'Fetch Cert' and then
|
|
have the Server make an initial connection.
|
|
|
|
If you do not want to save the certificate of
|
|
the VNC Server making the Reverse connection,
|
|
you must disable 'Verify All Certs' (note that
|
|
this means the server authenticity will not be
|
|
checked.)
|
|
}
|
|
|
|
button .lvd.ok -text OK -command {destroy .lvd}
|
|
button .lvd.ok2 -text OK -command {destroy .lvd}
|
|
button .lvd.disable -text "Disable 'Verify All Certs'" -command {set always_verify_ssl 0; destroy .lvd}
|
|
global uname
|
|
if {$uname == "Darwin"} {
|
|
pack .lvd.t .lvd.ok2 .lvd.disable .lvd.ok -side top -fill x
|
|
} else {
|
|
pack .lvd.t .lvd.disable .lvd.ok -side top -fill x
|
|
}
|
|
center_win .lvd
|
|
update
|
|
|
|
tkwait window .lvd
|
|
update
|
|
after 50
|
|
update
|
|
|
|
set did_listen_verify_all_dialog 1
|
|
return 1
|
|
}
|
|
|
|
proc reset_stunnel_extra_opts {} {
|
|
global stunnel_extra_opts0 stunnel_extra_svc_opts0 env
|
|
global ssvnc_multiple_listen0
|
|
if {$stunnel_extra_opts0 != "none"} {
|
|
set env(STUNNEL_EXTRA_OPTS) $stunnel_extra_opts0
|
|
}
|
|
if {$stunnel_extra_svc_opts0 != "none"} {
|
|
set env(STUNNEL_EXTRA_SVC_OPTS) $stunnel_extra_svc_opts0
|
|
}
|
|
set env(SSVNC_LIM_ACCEPT_PRELOAD) ""
|
|
if {$ssvnc_multiple_listen0 != "none"} {
|
|
set env(SSVNC_MULTIPLE_LISTEN) $ssvnc_multiple_listen0
|
|
}
|
|
set env(SSVNC_ULTRA_DSM) ""
|
|
set env(SSVNC_TURBOVNC) ""
|
|
catch { unset env(VNCVIEWER_NO_PIPELINE_UPDATES) }
|
|
catch { unset env(VNCVIEWER_NOTTY) }
|
|
catch { unset env(SSVNC_ACCEPT_POPUP) }
|
|
catch { unset env(SSVNC_ACCEPT_POPUP_SC) }
|
|
catch { unset env(SSVNC_KNOWN_HOSTS_FILE) }
|
|
}
|
|
|
|
proc maybe_add_vencrypt {proxy hp} {
|
|
global vencrypt_detected server_vencrypt
|
|
set vpd ""
|
|
if {$vencrypt_detected != ""} {
|
|
set vpd $vencrypt_detected
|
|
set vencrypt_detected ""
|
|
} elseif {$server_vencrypt} {
|
|
set vpd [get_vencrypt_proxy $hp]
|
|
}
|
|
if {$vpd != ""} {
|
|
mesg "vencrypt proxy: $vpd"
|
|
if {$proxy != ""} {
|
|
set proxy "$proxy,$vpd"
|
|
} else {
|
|
set proxy "$vpd"
|
|
}
|
|
}
|
|
return $proxy
|
|
}
|
|
|
|
proc no_certs_tutorial_mesg {} {
|
|
global svcert crtdir
|
|
global server_anondh
|
|
global always_verify_ssl
|
|
|
|
set doit 0
|
|
if {!$always_verify_ssl} {
|
|
if {$svcert == ""} {
|
|
if {$crtdir == "" || $crtdir == "ACCEPTED_CERTS"} {
|
|
set doit 1
|
|
}
|
|
}
|
|
} elseif {$server_anondh} {
|
|
set doit 1
|
|
}
|
|
if {$doit} {
|
|
mesg "INFO: without Certificate checking man-in-the-middle attack is possible."
|
|
} else {
|
|
set str ""
|
|
catch {set str [.l cget -text]}
|
|
if {$str != "" && [regexp {^INFO: without Certificate} $str]} {
|
|
mesg ""
|
|
}
|
|
}
|
|
}
|
|
|
|
proc vencrypt_tutorial_mesg {} {
|
|
global use_ssh use_sshssl use_listen
|
|
global server_vencrypt no_probe_vencrypt
|
|
global ultra_dsm
|
|
|
|
set m ""
|
|
if {$use_ssh} {
|
|
;
|
|
} elseif {$server_vencrypt} {
|
|
;
|
|
} elseif {$ultra_dsm} {
|
|
;
|
|
} elseif {$use_listen} {
|
|
set m "No VeNCrypt Auto-Detection: Listen mode."
|
|
} elseif {$use_sshssl} {
|
|
set m "No VeNCrypt Auto-Detection: SSH+SSL mode."
|
|
} elseif {$no_probe_vencrypt} {
|
|
set m "No VeNCrypt Auto-Detection: Disabled."
|
|
}
|
|
if {$m != ""} {
|
|
mesg $m
|
|
after 1000
|
|
}
|
|
return $m
|
|
|
|
#global svcert always_verify_ssl
|
|
#$svcert != "" || !$always_verify_ssl
|
|
# set m "No VeNCrypt Auto-Detection: 'Verify All Certs' disabled"
|
|
}
|
|
|
|
proc launch_unix {hp} {
|
|
global smb_redir_0 smb_mounts env
|
|
global vncauth_passwd use_unixpw unixpw_username unixpw_passwd
|
|
global ssh_only ts_only use_x11cursor use_nobell use_rawlocal use_notty use_popupfix ssvnc_scale ssvnc_escape
|
|
global ssvnc_encodings ssvnc_extra_opts
|
|
|
|
globalize
|
|
|
|
set cmd ""
|
|
|
|
if {[regexp {^vncssh://} $hp] || [regexp {^vnc\+ssh://} $hp]} {
|
|
set use_ssl 0
|
|
set use_ssh 1
|
|
sync_use_ssl_ssh
|
|
} elseif {[regexp {^vncs://} $hp] || [regexp {^vncssl://} $hp] || [regexp {^vnc\+ssl://} $hp]} {
|
|
set use_ssl 1
|
|
set use_ssh 0
|
|
sync_use_ssl_ssh
|
|
}
|
|
if {[regexp {^rsh:/?/?} $hp]} {
|
|
set use_ssl 0
|
|
set use_ssh 1
|
|
sync_use_ssl_ssh
|
|
}
|
|
|
|
check_ssh_needed
|
|
|
|
set_smb_mounts
|
|
|
|
global did_port_knock
|
|
set did_port_knock 0
|
|
set pk_hp ""
|
|
|
|
set skip_ssh 0
|
|
set do_direct 0
|
|
|
|
if [regexp {vnc://} $hp] {
|
|
set skip_ssh 1
|
|
set do_direct 1
|
|
if {! [info exists env(SSVNC_NO_ENC_WARN)]} {
|
|
direct_connect_msg
|
|
}
|
|
}
|
|
|
|
listen_verify_all_dialog $hp
|
|
|
|
if {! $do_direct} {
|
|
if {! [check_for_listen_ssl_cert]} {
|
|
return
|
|
}
|
|
}
|
|
|
|
global stunnel_extra_opts0 stunnel_extra_svc_opts0
|
|
set stunnel_extra_opts0 ""
|
|
set stunnel_extra_svc_opts0 ""
|
|
global ssvnc_multiple_listen0
|
|
set ssvnc_multiple_listen0 ""
|
|
|
|
if {[regexp -nocase {sslrepeater://} $hp]} {
|
|
if {$disable_ssl_workarounds} {
|
|
set disable_ssl_workarounds 0
|
|
mesg "Disabling SSL workarounds for 'UVNC Single Click III Bug'"
|
|
after 400
|
|
}
|
|
}
|
|
|
|
if [info exists env(STUNNEL_EXTRA_OPTS)] {
|
|
set stunnel_extra_opts0 $env(STUNNEL_EXTRA_OPTS)
|
|
if {$disable_ssl_workarounds} {
|
|
if {$disable_ssl_workarounds_type == "none"} {
|
|
;
|
|
} elseif {$disable_ssl_workarounds_type == "noempty"} {
|
|
set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = DONT_INSERT_EMPTY_FRAGMENTS"
|
|
}
|
|
} else {
|
|
set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = ALL"
|
|
}
|
|
} else {
|
|
if {$disable_ssl_workarounds} {
|
|
if {$disable_ssl_workarounds_type == "none"} {
|
|
;
|
|
} elseif {$disable_ssl_workarounds_type == "noempty"} {
|
|
set env(STUNNEL_EXTRA_OPTS) "options = DONT_INSERT_EMPTY_FRAGMENTS"
|
|
}
|
|
} else {
|
|
set env(STUNNEL_EXTRA_OPTS) "options = ALL"
|
|
}
|
|
}
|
|
if {$stunnel_local_protection && ! $use_listen} {
|
|
if {$stunnel_local_protection_type == "ident"} {
|
|
set user ""
|
|
if {[info exists env(USER)]} {
|
|
set user $env(USER)
|
|
} elseif {[info exists env(LOGNAME)]} {
|
|
set user $env(USER)
|
|
}
|
|
if {$user != ""} {
|
|
if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] {
|
|
set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS)
|
|
set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\nident = $user"
|
|
} else {
|
|
set env(STUNNEL_EXTRA_SVC_OPTS) "ident = $user"
|
|
}
|
|
}
|
|
} elseif {$stunnel_local_protection_type == "exec"} {
|
|
if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] {
|
|
set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS)
|
|
set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\n#stunnel-exec"
|
|
} else {
|
|
set env(STUNNEL_EXTRA_SVC_OPTS) "#stunnel-exec"
|
|
}
|
|
}
|
|
}
|
|
if {$ultra_dsm} {
|
|
if {$ultra_dsm_type == "securevnc"} {
|
|
;
|
|
} elseif {![file exists $ultra_dsm_file] && ![regexp {pw=} $ultra_dsm_file]} {
|
|
mesg "DSM key file does exist: $ultra_dsm_file"
|
|
bell
|
|
after 1000
|
|
return
|
|
}
|
|
global vncauth_passwd
|
|
if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} {
|
|
if {![info exists vncauth_passwd] || $vncauth_passwd == ""} {
|
|
mesg "For DSM pw=VNCPASSWD you must supply the VNC Password"
|
|
bell
|
|
after 1000
|
|
return
|
|
}
|
|
if [regexp {'} $vncauth_passwd] {
|
|
mesg "For DSM pw=VNCPASSWD password must not contain single quotes."
|
|
bell
|
|
after 1000
|
|
return
|
|
}
|
|
}
|
|
set dsm "ultravnc_dsm_helper "
|
|
if {$ultra_dsm_noultra} {
|
|
append dsm "noultra:"
|
|
}
|
|
if {$use_listen} {
|
|
append dsm "rev:"
|
|
}
|
|
if {$ultra_dsm_type == "guess"} {
|
|
append dsm "."
|
|
} else {
|
|
append dsm $ultra_dsm_type
|
|
}
|
|
if {$ultra_dsm_noultra} {
|
|
if {$ultra_dsm_salt != ""} {
|
|
append dsm "@$ultra_dsm_salt"
|
|
}
|
|
}
|
|
if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} {
|
|
append dsm " pw='$vncauth_passwd'"
|
|
} else {
|
|
if {$ultra_dsm_file == "" && $ultra_dsm_type == "securevnc"} {
|
|
append dsm " none"
|
|
} else {
|
|
append dsm " $ultra_dsm_file"
|
|
}
|
|
}
|
|
set env(SSVNC_ULTRA_DSM) $dsm
|
|
}
|
|
if {$multiple_listen && $use_listen} {
|
|
if [info exists env(SSVNC_MULTIPLE_LISTEN)] {
|
|
set ssvnc_multiple_listen0 $env(SSVNC_MULTIPLE_LISTEN)
|
|
}
|
|
set env(SSVNC_MULTIPLE_LISTEN) "1"
|
|
}
|
|
|
|
if {$use_ssh} {
|
|
;
|
|
} elseif {$use_sshssl} {
|
|
;
|
|
} elseif {$use_ssl} {
|
|
set prox [get_ssh_proxy $hp]
|
|
if {$prox != "" && [regexp {@} $prox]} {
|
|
mesg "Error: proxy contains '@' Did you mean to use SSH mode?"
|
|
bell
|
|
return
|
|
}
|
|
if [regexp {@} $hp] {
|
|
mesg "Error: host contains '@' Did you mean to use SSH mode?"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
|
|
if {$use_ssh || $use_sshssl} {
|
|
if {$ssh_local_protection} {
|
|
if {![info exists env(LIM_ACCEPT)]} {
|
|
set env(LIM_ACCEPT) 1
|
|
}
|
|
if {![info exists env(LIM_ACCEPT_TIME)]} {
|
|
set env(LIM_ACCEPT_TIME) 35
|
|
}
|
|
set env(SSVNC_LIM_ACCEPT_PRELOAD) "lim_accept.so"
|
|
mesg "SSH LIM_ACCEPT($env(LIM_ACCEPT),$env(LIM_ACCEPT_TIME)): lim_accept.so"
|
|
after 700
|
|
}
|
|
if {$skip_ssh || $ultra_dsm} {
|
|
set cmd "ss_vncviewer"
|
|
} elseif {$use_ssh} {
|
|
set cmd "ss_vncviewer -ssh"
|
|
} else {
|
|
set cmd "ss_vncviewer -sshssl"
|
|
if {$mycert != ""} {
|
|
set cmd "$cmd -mycert '$mycert'"
|
|
}
|
|
if {$crlfil != ""} {
|
|
set cmd "$cmd -crl '$crlfil'"
|
|
}
|
|
if {$svcert != ""} {
|
|
set cmd "$cmd -verify '$svcert'"
|
|
} elseif {$crtdir != "" && $crtdir != "ACCEPTED_CERTS"} {
|
|
set cmd "$cmd -verify '$crtdir'"
|
|
}
|
|
}
|
|
if {$use_listen} {
|
|
set cmd "$cmd -listen"
|
|
}
|
|
if {$ssh_local_protection} {
|
|
regsub {ss_vncviewer} $cmd "ssvnc_cmd" cmd
|
|
}
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
set sshcmd [get_ssh_cmd $hp]
|
|
|
|
if {$use_sshssl} {
|
|
if {!$do_direct} {
|
|
set proxy [maybe_add_vencrypt $proxy $hp]
|
|
}
|
|
}
|
|
|
|
if {$ts_only} {
|
|
regsub {:0$} $hpnew "" hpnew
|
|
if {$proxy == ""} {
|
|
# XXX host_part
|
|
if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} {
|
|
set proxy "$sshhst:$sshpt"
|
|
set hpnew "localhost"
|
|
}
|
|
} else {
|
|
if {![regexp {,} $proxy]} {
|
|
if {$hpnew != "localhost"} {
|
|
set proxy "$proxy,$hpnew"
|
|
set hpnew "localhost"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#puts hp=$hp
|
|
#puts hpn=$hpnew
|
|
#puts pxy=$proxy
|
|
#puts cmd=$sshcmd
|
|
|
|
set hp $hpnew
|
|
|
|
if {$proxy != ""} {
|
|
set cmd "$cmd -proxy '$proxy'"
|
|
set pk_hp $proxy
|
|
}
|
|
if {$pk_hp == ""} {
|
|
set pk_hp $hp
|
|
}
|
|
|
|
set do_pre 0
|
|
if {$use_smbmnt} {
|
|
set do_pre 1
|
|
} elseif {$use_sound && $sound_daemon_kill} {
|
|
set do_pre 1
|
|
}
|
|
global skip_pre
|
|
if {$skip_pre || $skip_ssh} {
|
|
set do_pre 0
|
|
set skip_pre 0
|
|
}
|
|
|
|
set tag [contag]
|
|
|
|
if {$do_pre} {
|
|
do_unix_pre $tag $proxy $hp $pk_hp
|
|
}
|
|
|
|
|
|
set setup_cmds [ugly_setup_scripts post $tag]
|
|
|
|
if {$skip_ssh} {
|
|
set setup_cmds ""
|
|
}
|
|
if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} {
|
|
global use_cups cups_x11vnc cups_remote_port
|
|
global cups_remote_smb_port
|
|
global use_sound sound_daemon_x11vnc sound_daemon_remote_port
|
|
global ts_only
|
|
if {$ts_only} {
|
|
set cups_x11vnc 1
|
|
set sound_daemon_x11vnc 1
|
|
}
|
|
if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} {
|
|
set crp $cups_remote_port
|
|
if {$ts_only} {
|
|
set cups_remote_port [rand_port]
|
|
set crp "DAEMON-$cups_remote_port"
|
|
}
|
|
set sshcmd "$sshcmd -env FD_CUPS=$crp"
|
|
}
|
|
if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} {
|
|
set csp $cups_remote_smb_port
|
|
if {$ts_only} {
|
|
set cups_remote_smb_port [rand_port]
|
|
set csp "DAEMON-$cups_remote_smb_port"
|
|
}
|
|
set sshcmd "$sshcmd -env FD_SMB=$csp"
|
|
}
|
|
if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} {
|
|
set srp $sound_daemon_remote_port
|
|
if {$ts_only} {
|
|
set sound_daemon_remote_port [rand_port]
|
|
set srp "DAEMON-$sound_daemon_remote_port"
|
|
}
|
|
set sshcmd "$sshcmd -env FD_ESD=$srp"
|
|
}
|
|
}
|
|
|
|
if {$sshcmd == "SHELL"} {
|
|
set env(SS_VNCVIEWER_SSH_CMD) {$SHELL}
|
|
set env(SS_VNCVIEWER_SSH_ONLY) 1
|
|
} elseif {$setup_cmds != ""} {
|
|
if {$sshcmd == ""} {
|
|
set sshcmd "sleep 15"
|
|
}
|
|
set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds$sshcmd"
|
|
} else {
|
|
if {$sshcmd != ""} {
|
|
set cmd "$cmd -sshcmd '$sshcmd'"
|
|
}
|
|
}
|
|
|
|
set sshargs ""
|
|
if {$use_cups} {
|
|
append sshargs [get_cups_redir]
|
|
}
|
|
if {$use_sound} {
|
|
append sshargs [get_sound_redir]
|
|
}
|
|
if {$additional_port_redirs} {
|
|
append sshargs [get_additional_redir]
|
|
}
|
|
|
|
set sshargs [string trim $sshargs]
|
|
if {$skip_ssh} {
|
|
set sshargs ""
|
|
}
|
|
if {$sshargs != ""} {
|
|
set cmd "$cmd -sshargs '$sshargs'"
|
|
set env(SS_VNCVIEWER_USE_C) 1
|
|
} else {
|
|
# hmm we used to have it off... why?
|
|
# ssh typing response?
|
|
set env(SS_VNCVIEWER_USE_C) 1
|
|
}
|
|
if {$sshcmd == "SHELL"} {
|
|
set env(SS_VNCVIEWER_SSH_ONLY) 1
|
|
if {$proxy == ""} {
|
|
set hpt $hpnew
|
|
# XXX host_part
|
|
regsub {:[0-9][0-9]*$} $hpt "" hpt
|
|
set cmd "$cmd -proxy '$hpt'"
|
|
}
|
|
set geometry [xterm_center_geometry]
|
|
if {$pk_hp == ""} {
|
|
set pk_hp $hp
|
|
}
|
|
if {! $did_port_knock} {
|
|
if {! [do_port_knock $pk_hp start]} {
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
set did_port_knock 1
|
|
}
|
|
|
|
if {[regexp {FINISH} $port_knocking_list]} {
|
|
wm withdraw .
|
|
update
|
|
unix_terminal_cmd $geometry "SHELL to $hp" "$cmd"
|
|
wm deiconify .
|
|
update
|
|
do_port_knock $pk_hp finish
|
|
} else {
|
|
unix_terminal_cmd $geometry "SHELL to $hp" "$cmd" 1
|
|
}
|
|
set env(SS_VNCVIEWER_SSH_CMD) ""
|
|
set env(SS_VNCVIEWER_SSH_ONLY) ""
|
|
set env(SS_VNCVIEWER_USE_C) ""
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
} else {
|
|
set cmd "ssvnc_cmd"
|
|
set hpnew [get_ssh_hp $hp]
|
|
set proxy [get_ssh_proxy $hp]
|
|
|
|
if {!$do_direct && ![repeater_proxy_check $proxy]} {
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
|
|
if {! $do_direct && ! $ultra_dsm && ![regexp -nocase {ssh://} $hpnew]} {
|
|
set did_check 0
|
|
if {$mycert != ""} {
|
|
set cmd "$cmd -mycert '$mycert'"
|
|
}
|
|
if {$crlfil != ""} {
|
|
set cmd "$cmd -crl '$crlfil'"
|
|
}
|
|
if {$svcert != ""} {
|
|
set cmd "$cmd -verify '$svcert'"
|
|
} elseif {$crtdir != ""} {
|
|
if {$crtdir == "ACCEPTED_CERTS"} {
|
|
global skip_verify_accepted_certs
|
|
set skip_verify_accepted_certs 0
|
|
|
|
set did_check 1
|
|
if {! [check_accepted_certs 0]} {
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
if {! $skip_verify_accepted_certs} {
|
|
set adir [get_idir_certs ""]
|
|
set adir "$adir/accepted"
|
|
catch {file mkdir $adir}
|
|
set cmd "$cmd -verify '$adir'"
|
|
}
|
|
|
|
} else {
|
|
set cmd "$cmd -verify '$crtdir'"
|
|
}
|
|
}
|
|
if {! $did_check} {
|
|
check_accepted_certs 1
|
|
}
|
|
}
|
|
|
|
if {!$do_direct} {
|
|
set proxy [maybe_add_vencrypt $proxy $hp]
|
|
}
|
|
|
|
if {$proxy != ""} {
|
|
set cmd "$cmd -proxy '$proxy'"
|
|
}
|
|
set hp $hpnew
|
|
if [regexp {^.*@} $hp match] {
|
|
catch {raise .; update}
|
|
mesg "Trimming \"$match\" from hostname"
|
|
after 700
|
|
regsub {^.*@} $hp "" hp
|
|
}
|
|
if [regexp {@} $proxy] {
|
|
bell
|
|
catch {raise .; update}
|
|
mesg "WARNING: SSL proxy contains \"@\" sign"
|
|
after 1500
|
|
}
|
|
}
|
|
|
|
global anon_dh_detected
|
|
if {$anon_dh_detected || $server_anondh} {
|
|
if {!$do_direct} {
|
|
set cmd "$cmd -anondh"
|
|
}
|
|
set anon_dh_detected 0
|
|
}
|
|
if {$use_alpha} {
|
|
set cmd "$cmd -alpha"
|
|
}
|
|
if {$use_send_clipboard} {
|
|
set cmd "$cmd -sendclipboard"
|
|
}
|
|
if {$use_send_always} {
|
|
set cmd "$cmd -sendalways"
|
|
}
|
|
if {$use_turbovnc} {
|
|
set env(SSVNC_TURBOVNC) 1
|
|
}
|
|
if {$disable_pipeline} {
|
|
set env(VNCVIEWER_NO_PIPELINE_UPDATES) 1
|
|
}
|
|
if {$ssh_known_hosts_filename != ""} {
|
|
set env(SSVNC_KNOWN_HOSTS_FILE) $ssh_known_hosts_filename
|
|
}
|
|
if {$use_grab} {
|
|
set cmd "$cmd -grab"
|
|
}
|
|
if {$use_x11cursor} {
|
|
set cmd "$cmd -x11cursor"
|
|
}
|
|
if {$use_nobell} {
|
|
set cmd "$cmd -nobell"
|
|
}
|
|
if {$use_rawlocal} {
|
|
set cmd "$cmd -rawlocal"
|
|
}
|
|
if {$use_notty} {
|
|
set env(VNCVIEWER_NOTTY) 1
|
|
}
|
|
if {$use_popupfix} {
|
|
set cmd "$cmd -popupfix"
|
|
}
|
|
if {$ssvnc_scale != ""} {
|
|
set cmd "$cmd -scale '$ssvnc_scale'"
|
|
}
|
|
if {$ssvnc_escape != ""} {
|
|
set cmd "$cmd -escape '$ssvnc_escape'"
|
|
}
|
|
if {$ssvnc_encodings != ""} {
|
|
set cmd "$cmd -ssvnc_encodings '$ssvnc_encodings'"
|
|
}
|
|
if {$ssvnc_extra_opts != ""} {
|
|
set cmd "$cmd -ssvnc_extra_opts '$ssvnc_extra_opts'"
|
|
}
|
|
if {$rfbversion != ""} {
|
|
set cmd "$cmd -rfbversion '$rfbversion'"
|
|
}
|
|
if {$vncviewer_realvnc4} {
|
|
set cmd "$cmd -realvnc4"
|
|
}
|
|
if {$use_listen} {
|
|
set cmd "$cmd -listen"
|
|
if {$listen_once} {
|
|
set cmd "$cmd -onelisten"
|
|
}
|
|
if {$listen_accept_popup} {
|
|
if {$listen_accept_popup_sc} {
|
|
set env(SSVNC_ACCEPT_POPUP_SC) 1
|
|
} else {
|
|
set env(SSVNC_ACCEPT_POPUP) 1
|
|
}
|
|
}
|
|
}
|
|
|
|
global darwin_cotvnc
|
|
if {$darwin_cotvnc} {
|
|
set env(DARWIN_COTVNC) 1
|
|
} else {
|
|
if [info exists env(DISPLAY)] {
|
|
if {$env(DISPLAY) != ""} {
|
|
set env(DARWIN_COTVNC) 0
|
|
} else {
|
|
set env(DARWIN_COTVNC) 1
|
|
}
|
|
} else {
|
|
set env(DARWIN_COTVNC) 1
|
|
}
|
|
}
|
|
|
|
set do_vncspacewrapper 0
|
|
if {$change_vncviewer && $change_vncviewer_path != ""} {
|
|
set path [string trim $change_vncviewer_path]
|
|
if [regexp {^["'].} $path] { # "
|
|
set tmp "/tmp/vncspacewrapper.[tpid]"
|
|
set tmp [mytmp $tmp]
|
|
set do_vncspacewrapper 1
|
|
if {0} {
|
|
catch {file delete $tmp}
|
|
if {[file exists $tmp]} {
|
|
catch {destroy .c}
|
|
mesg "file still exists: $tmp"
|
|
bell
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
}
|
|
catch {set fh [open $tmp "w"]}
|
|
catch {exec chmod 700 $tmp}
|
|
if {! [file exists $tmp]} {
|
|
catch {destroy .c}
|
|
mesg "cannot create: $tmp"
|
|
bell
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
puts $fh "#!/bin/sh"
|
|
puts $fh "echo $tmp; set -xv"
|
|
puts $fh "$path \"\$@\""
|
|
puts $fh "sleep 1; rm -f $tmp"
|
|
close $fh
|
|
set path $tmp
|
|
}
|
|
set env(VNCVIEWERCMD) $path
|
|
} else {
|
|
if [info exists env(VNCVIEWERCMD_OVERRIDE)] {
|
|
set env(VNCVIEWERCMD) $env(VNCVIEWERCMD_OVERRIDE)
|
|
} else {
|
|
set env(VNCVIEWERCMD) ""
|
|
}
|
|
}
|
|
|
|
set realvnc4 $vncviewer_realvnc4
|
|
set realvnc3 0
|
|
set flavor ""
|
|
if {! $darwin_cotvnc} {
|
|
set done 0
|
|
if {$do_vncspacewrapper} {
|
|
if [regexp -nocase {ultra} $change_vncviewer_path] {
|
|
set done 1
|
|
set flavor "ultravnc"
|
|
} elseif [regexp -nocase {chicken.of} $change_vncviewer_path] {
|
|
set done 1
|
|
set flavor "cotvnc"
|
|
}
|
|
}
|
|
if {! $done} {
|
|
catch {set flavor [exec ss_vncviewer -viewerflavor 2>/dev/null]}
|
|
}
|
|
}
|
|
if [regexp {realvnc4} $flavor] {
|
|
set realvnc4 1
|
|
}
|
|
if [regexp {tightvnc} $flavor] {
|
|
set realvnc4 0
|
|
}
|
|
if [regexp {realvnc3} $flavor] {
|
|
set realvnc4 0
|
|
set realvnc3 1
|
|
}
|
|
if {$realvnc4} {
|
|
set cmd "$cmd -realvnc4"
|
|
}
|
|
|
|
set cmd "$cmd $hp"
|
|
|
|
set passwdfile ""
|
|
if {$vncauth_passwd != ""} {
|
|
global use_listen
|
|
set footest [mytmp /tmp/.check.[tpid]]
|
|
catch {file delete $footest}
|
|
global mktemp
|
|
set passwdfile "/tmp/.vncauth_tmp.[tpid]"
|
|
if {$mktemp == ""} {
|
|
set passwdfile "$env(SSVNC_HOME)/.vncauth_tmp.[tpid]"
|
|
}
|
|
|
|
set passwdfile [mytmp $passwdfile]
|
|
catch {exec vncstorepw $vncauth_passwd $passwdfile}
|
|
catch {exec chmod 600 $passwdfile}
|
|
if {$use_listen} {
|
|
global env
|
|
set env(SS_VNCVIEWER_RM) $passwdfile
|
|
} else {
|
|
if {$darwin_cotvnc} {
|
|
catch {exec sh -c "sleep 60; rm $passwdfile 2>/dev/null" &}
|
|
} else {
|
|
catch {exec sh -c "sleep 20; rm $passwdfile 2>/dev/null" &}
|
|
}
|
|
}
|
|
if {$darwin_cotvnc} {
|
|
set cmd "$cmd --PasswordFile $passwdfile"
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} else {
|
|
set cmd "$cmd -passwd $passwdfile"
|
|
}
|
|
}
|
|
|
|
if {$use_viewonly} {
|
|
if {$darwin_cotvnc} {
|
|
set cmd "$cmd --ViewOnly"
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} elseif {$flavor == "ultravnc"} {
|
|
set cmd "$cmd /viewonly"
|
|
} else {
|
|
set cmd "$cmd -viewonly"
|
|
}
|
|
}
|
|
if {$use_fullscreen} {
|
|
if {$darwin_cotvnc} {
|
|
set cmd "$cmd --FullScreen"
|
|
} elseif {$flavor == "ultravnc"} {
|
|
set cmd "$cmd /fullscreen"
|
|
} elseif {$flavor == "unknown"} {
|
|
if [regexp {vinagre} $change_vncviewer_path] {
|
|
set cmd "$cmd -f"
|
|
}
|
|
} else {
|
|
set cmd "$cmd -fullscreen"
|
|
}
|
|
}
|
|
if {$use_bgr233} {
|
|
if {$realvnc4} {
|
|
set cmd "$cmd -lowcolourlevel 1"
|
|
} elseif {$flavor == "ultravnc"} {
|
|
set cmd "$cmd /8bit"
|
|
} elseif {$flavor == "ultravnc"} {
|
|
;
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} else {
|
|
set cmd "$cmd -bgr233"
|
|
}
|
|
}
|
|
if {$use_nojpeg} {
|
|
if {$darwin_cotvnc} {
|
|
;
|
|
} elseif {$flavor == "ultravnc"} {
|
|
;
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} elseif {! $realvnc4 && ! $realvnc3} {
|
|
set cmd "$cmd -nojpeg"
|
|
}
|
|
}
|
|
if {! $use_raise_on_beep} {
|
|
if {$darwin_cotvnc} {
|
|
;
|
|
} elseif {$flavor == "ultravnc"} {
|
|
;
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} elseif {! $realvnc4 && ! $realvnc3} {
|
|
set cmd "$cmd -noraiseonbeep"
|
|
}
|
|
}
|
|
if {$use_compresslevel != "" && $use_compresslevel != "default"} {
|
|
if {$realvnc3} {
|
|
;
|
|
} elseif {$flavor == "ultravnc"} {
|
|
;
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} elseif {$realvnc4} {
|
|
set cmd "$cmd -zliblevel '$use_compresslevel'"
|
|
} else {
|
|
set cmd "$cmd -compresslevel '$use_compresslevel'"
|
|
}
|
|
}
|
|
if {$use_quality != "" && $use_quality != "default"} {
|
|
if {$darwin_cotvnc} {
|
|
;
|
|
} elseif {$flavor == "ultravnc"} {
|
|
;
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} elseif {! $realvnc4 && ! $realvnc3} {
|
|
set cmd "$cmd -quality '$use_quality'"
|
|
}
|
|
}
|
|
if {$use_ssh || $use_sshssl} {
|
|
# realvnc4 -preferredencoding zrle
|
|
if {$darwin_cotvnc} {
|
|
;
|
|
} elseif {$flavor == "ultravnc"} {
|
|
;
|
|
} elseif {$flavor == "unknown"} {
|
|
;
|
|
} elseif {$realvnc4} {
|
|
set cmd "$cmd -preferredencoding zrle"
|
|
} else {
|
|
set cmd "$cmd -encodings 'copyrect tight zrle zlib hextile'"
|
|
}
|
|
}
|
|
|
|
global ycrop_string
|
|
global sbwid_string
|
|
catch {unset env(VNCVIEWER_SBWIDTH)}
|
|
catch {unset env(VNCVIEWER_YCROP)}
|
|
if {[info exists ycrop_string] && $ycrop_string != ""} {
|
|
set t $ycrop_string
|
|
if [regexp {,sb=([0-9][0-9]*)} $t m mv1] {
|
|
set env(VNCVIEWER_SBWIDTH) $mv1
|
|
}
|
|
regsub {,sb=([0-9][0-9]*)} $t "" t
|
|
if {$t != ""} {
|
|
set env(VNCVIEWER_YCROP) $t
|
|
}
|
|
}
|
|
if {[info exists sbwid_string] && $sbwid_string != ""} {
|
|
set t $sbwid_string
|
|
set env(VNCVIEWER_SBWIDTH) $sbwid_string
|
|
if {$t != ""} {
|
|
set env(VNCVIEWER_SBWIDTH) $t
|
|
}
|
|
}
|
|
|
|
catch {destroy .o}
|
|
catch {destroy .oa}
|
|
catch {destroy .os}
|
|
update
|
|
|
|
if {$use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} {
|
|
mesg "running: $sound_daemon_local_cmd"
|
|
global sound_daemon_local_pid
|
|
set sound_daemon_local_pid ""
|
|
#exec sh -c "$sound_daemon_local_cmd " >& /dev/null </dev/null &
|
|
set sound_daemon_local_pid [exec sh -c "echo \$\$; exec $sound_daemon_local_cmd </dev/null 1>/dev/null 2>/dev/null &"]
|
|
update
|
|
after 500
|
|
}
|
|
|
|
if {$pk_hp == ""} {
|
|
set pk_hp $hp
|
|
}
|
|
if {! $did_port_knock} {
|
|
if {! [do_port_knock $pk_hp start]} {
|
|
wm deiconify .
|
|
update
|
|
reset_stunnel_extra_opts
|
|
return
|
|
}
|
|
set did_port_knock 1
|
|
}
|
|
|
|
init_unixpw $hp
|
|
|
|
if {! $do_direct} {
|
|
vencrypt_tutorial_mesg
|
|
}
|
|
|
|
wm withdraw .
|
|
update
|
|
|
|
set geometry [xterm_center_geometry]
|
|
set xrm1 "*.srinterCommand:true"
|
|
set xrm2 $xrm1
|
|
set xrm3 $xrm1
|
|
if {[info exists env(SSVNC_GUI_CMD)]} {
|
|
set xrm1 "*.printerCommand:env XTERM_PRINT=1 $env(SSVNC_GUI_CMD)"
|
|
set xrm2 "XTerm*VT100*translations:#override Shift<Btn3Down>:print()\\nCtrl<Key>N:print()"
|
|
set xrm3 "*mainMenu*print*Label: New SSVNC_GUI"
|
|
}
|
|
set m "Done. You Can X-out or Ctrl-C this Terminal if you like. Use Ctrl-\\\\ to pause."
|
|
global uname
|
|
if {$uname == "Darwin"} {
|
|
regsub {X-out or } $m "" m
|
|
}
|
|
set te "set -xv; "
|
|
if {$ts_only} {
|
|
set te ""
|
|
}
|
|
|
|
global extra_sleep
|
|
set ssvnc_extra_sleep_save ""
|
|
if {$extra_sleep != ""} {
|
|
if [info exists env(SSVNC_EXTRA_SLEEP)] {
|
|
set ssvnc_extra_sleep_save $env(SSVNC_EXTRA_SLEEP)
|
|
}
|
|
set env(SSVNC_EXTRA_SLEEP) $extra_sleep
|
|
}
|
|
|
|
set sstx "SSL/SSH VNC Viewer"
|
|
set hptx $hp
|
|
global use_listen
|
|
if {$use_listen} {
|
|
set sstx "SSVNC"
|
|
set hptx "$hp (Press Ctrl-C to Stop Listening)"
|
|
}
|
|
|
|
|
|
set s1 5
|
|
set s2 4
|
|
if [info exists env(SSVNC_FINISH_SLEEP)] {
|
|
set s1 $env(SSVNC_FINISH_SLEEP);
|
|
set s2 $s1
|
|
}
|
|
|
|
unix_terminal_cmd $geometry "$sstx $hptx" \
|
|
"$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
|
|
|
|
set env(SS_VNCVIEWER_SSH_CMD) ""
|
|
set env(SS_VNCVIEWER_USE_C) ""
|
|
|
|
if {$extra_sleep != ""} {
|
|
if {$ssvnc_extra_sleep_save != ""} {
|
|
set env(SSVNC_EXTRA_SLEEP) $ssvnc_extra_sleep_save
|
|
} else {
|
|
catch {unset env(SSVNC_EXTRA_SLEEP)}
|
|
}
|
|
}
|
|
|
|
if {$use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
|
|
# XXX need to kill just one...
|
|
set daemon [string trim $sound_daemon_local_cmd]
|
|
regsub {^gw[ \t]*} $daemon "" daemon
|
|
regsub {[ \t].*$} $daemon "" daemon
|
|
regsub {^.*/} $daemon "" daemon
|
|
mesg "killing sound daemon: $daemon"
|
|
global sound_daemon_local_pid
|
|
if {$sound_daemon_local_pid != ""} {
|
|
#puts pid=$sound_daemon_local_pid
|
|
catch {exec sh -c "kill $sound_daemon_local_pid" >/dev/null 2>/dev/null </dev/null &}
|
|
incr sound_daemon_local_pid
|
|
catch {exec sh -c "kill $sound_daemon_local_pid" >/dev/null 2>/dev/null </dev/null &}
|
|
set sound_daemon_local_pid ""
|
|
} elseif {$daemon != ""} {
|
|
catch {exec sh -c "killall $daemon" >/dev/null 2>/dev/null </dev/null &}
|
|
catch {exec sh -c "pkill -x $daemon" >/dev/null 2>/dev/null </dev/null &}
|
|
}
|
|
}
|
|
if {$passwdfile != ""} {
|
|
catch {file delete $passwdfile}
|
|
}
|
|
wm deiconify .
|
|
mac_raise
|
|
mesg "Disconnected from $hp"
|
|
if {[regexp {FINISH} $port_knocking_list]} {
|
|
do_port_knock $pk_hp finish
|
|
}
|
|
|
|
reset_stunnel_extra_opts
|
|
|
|
fini_unixpw
|
|
}
|
|
|
|
proc kill_stunnel {pids} {
|
|
set count 0
|
|
foreach pid $pids {
|
|
mesg "killing STUNNEL pid: $pid"
|
|
winkill $pid
|
|
if {$count == 0} {
|
|
after 600
|
|
} else {
|
|
after 300
|
|
}
|
|
incr count
|
|
}
|
|
}
|
|
|
|
proc get_task_list {} {
|
|
global is_win9x
|
|
|
|
set output1 ""
|
|
set output2 ""
|
|
if {! $is_win9x} {
|
|
# try for tasklist on XP pro
|
|
catch {set output1 [exec tasklist.exe]}
|
|
}
|
|
catch {set output2 [exec w98/tlist.exe]}
|
|
|
|
set output $output1
|
|
append output "\n"
|
|
append output $output2
|
|
|
|
return $output
|
|
}
|
|
|
|
proc note_stunnel_pids {when} {
|
|
global is_win9x pids_before pids_after pids_new
|
|
|
|
if {$when == "before"} {
|
|
array unset pids_before
|
|
array unset pids_after
|
|
set pids_new {}
|
|
set pids_before(none) "none"
|
|
set pids_after(none) "none"
|
|
}
|
|
|
|
set output [get_task_list]
|
|
|
|
foreach line [split $output "\n\r"] {
|
|
set m 0
|
|
if [regexp -nocase {stunnel} $line] {
|
|
set m 1
|
|
} elseif [regexp -nocase {connect_br} $line] {
|
|
set m 1
|
|
}
|
|
if {$m} {
|
|
if [regexp {(-?[0-9][0-9]*)} $line m p] {
|
|
if {$when == "before"} {
|
|
set pids_before($p) $line
|
|
} else {
|
|
set pids_after($p) $line
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if {$when == "after"} {
|
|
foreach new [array names pids_after] {
|
|
if {! [info exists pids_before($new)]} {
|
|
lappend pids_new $new
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc del_launch_windows_ssh_files {} {
|
|
global launch_windows_ssh_files
|
|
global env
|
|
|
|
if {[info exists env(SSVNC_NO_DELETE)]} {
|
|
return
|
|
}
|
|
|
|
if {$launch_windows_ssh_files != ""} {
|
|
foreach tf [split $launch_windows_ssh_files] {
|
|
if {$tf == ""} {
|
|
continue
|
|
}
|
|
catch {file delete $tf}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc launch_shell_only {} {
|
|
global is_windows
|
|
global skip_pre
|
|
global use_ssl use_ssh use_sshssl
|
|
|
|
set hp [get_vncdisplay]
|
|
regsub {cmd=.*$} $hp "" hp
|
|
set hp [string trim $hp]
|
|
if {$is_windows} {
|
|
append hp " cmd=PUTTY"
|
|
} else {
|
|
append hp " cmd=SHELL"
|
|
}
|
|
set use_ssl_save $use_ssl
|
|
set use_ssh_save $use_ssh
|
|
set use_sshssl_save $use_sshssl
|
|
set skip_pre 1
|
|
if {! $use_ssh && ! $use_sshssl} {
|
|
set use_ssh 1
|
|
set use_ssl 1
|
|
}
|
|
launch $hp
|
|
|
|
set use_ssl $use_ssl_save
|
|
set use_ssh $use_ssh_save
|
|
set use_sshssl $use_sshssl_save
|
|
}
|
|
|
|
proc to_sshonly {} {
|
|
global ssh_only ts_only env
|
|
global showing_no_encryption
|
|
#if {$showing_no_encryption} {
|
|
# toggle_no_encryption
|
|
#}
|
|
if {$ssh_only && !$ts_only} {
|
|
return
|
|
}
|
|
if {[info exists env(SSVNC_TS_ALWAYS)]} {
|
|
return
|
|
}
|
|
set ssh_only 1
|
|
set ts_only 0
|
|
|
|
set t "SSH VNC Viewer"
|
|
wm title . $t
|
|
catch {pack forget .f4}
|
|
catch {pack forget .b.certs}
|
|
catch {.l configure -text $t}
|
|
|
|
global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
|
|
set vncdisplay ""
|
|
set vncauth_passwd ""
|
|
set unixpw_username ""
|
|
set vncproxy ""
|
|
set remote_ssh_cmd ""
|
|
|
|
set_defaults
|
|
}
|
|
|
|
proc toggle_tsonly {} {
|
|
global ts_only env
|
|
if {$ts_only} {
|
|
if {![info exists env(SSVNC_TS_ALWAYS)]} {
|
|
to_ssvnc
|
|
}
|
|
} else {
|
|
to_tsonly
|
|
}
|
|
}
|
|
|
|
proc toggle_sshonly {} {
|
|
global ssh_only env
|
|
if {$ssh_only} {
|
|
to_ssvnc
|
|
} else {
|
|
to_sshonly
|
|
}
|
|
}
|
|
|
|
proc to_tsonly {} {
|
|
global ts_only
|
|
global showing_no_encryption
|
|
#if {$showing_no_encryption} {
|
|
# toggle_no_encryption
|
|
#}
|
|
if {$ts_only} {
|
|
return
|
|
}
|
|
set ts_only 1
|
|
set ssh_only 1
|
|
|
|
set t "Terminal Services VNC Viewer"
|
|
wm title . $t
|
|
catch {pack forget .f4}
|
|
catch {pack forget .f3}
|
|
catch {pack forget .f1}
|
|
catch {pack forget .b.certs}
|
|
catch {.l configure -text $t}
|
|
catch {.f0.l configure -text "VNC Terminal Server:"}
|
|
|
|
global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
|
|
set vncdisplay ""
|
|
set vncauth_passwd ""
|
|
set unixpw_username ""
|
|
set vncproxy ""
|
|
set remote_ssh_cmd ""
|
|
|
|
set_defaults
|
|
}
|
|
|
|
proc to_ssvnc {} {
|
|
global ts_only ssh_only env
|
|
|
|
if {!$ts_only && !$ssh_only} {
|
|
return;
|
|
}
|
|
if {[info exists env(SSVNC_TS_ALWAYS)]} {
|
|
return
|
|
}
|
|
set ts_only 0
|
|
set ssh_only 0
|
|
|
|
set t "SSL/SSH VNC Viewer"
|
|
wm title . $t
|
|
catch {pack configure .f1 -after .f0 -side top -fill x}
|
|
catch {pack configure .f3 -after .f2 -side top -fill x}
|
|
catch {pack configure .f4 -after .f3 -side top -fill x}
|
|
catch {pack configure .b.certs -before .b.opts -side left -expand 1 -fill x}
|
|
catch {.l configure -text $t}
|
|
catch {.f0.l configure -text "VNC Host:Display"}
|
|
|
|
#global started_with_noenc
|
|
#if {$started_with_noenc} {
|
|
# toggle_no_encryption
|
|
#}
|
|
|
|
global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
|
|
set vncdisplay ""
|
|
set vncauth_passwd ""
|
|
set unixpw_username ""
|
|
set vncproxy ""
|
|
set remote_ssh_cmd ""
|
|
|
|
set_defaults
|
|
}
|
|
|
|
proc launch {{hp ""}} {
|
|
global tcl_platform is_windows
|
|
global mycert svcert crtdir crlfil
|
|
global pids_before pids_after pids_new
|
|
global env
|
|
global use_ssl use_ssh use_sshssl sshssl_sw use_listen disable_ssl_workarounds
|
|
global vncdisplay
|
|
|
|
set debug 0
|
|
if {$hp == ""} {
|
|
set hp [get_vncdisplay]
|
|
}
|
|
|
|
set hpt [string trim $hp]
|
|
regsub {[ ].*$} $hpt "" hpt
|
|
|
|
|
|
if {[regexp {^HOME=} $hpt] || [regexp {^SSVNC_HOME=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*HOME=} $t "" t
|
|
set t [string trim $t]
|
|
set env(SSVNC_HOME) $t
|
|
mesg "Set SSVNC_HOME to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^DISPLAY=} $hpt] || [regexp {^SSVNC_DISPLAY=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*DISPLAY=} $t "" t
|
|
set t [string trim $t]
|
|
set env(DISPLAY) $t
|
|
mesg "Set DISPLAY to $t"
|
|
set vncdisplay ""
|
|
global uname darwin_cotvnc
|
|
if {$uname == "Darwin"} {
|
|
if {$t != ""} {
|
|
set darwin_cotvnc 0
|
|
} else {
|
|
set darwin_cotvnc 1
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
if {[regexp {^DYLD_LIBRARY_PATH=} $hpt] || [regexp {^SSVNC_DYLD_LIBRARY_PATH=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*DYLD_LIBRARY_PATH=} $t "" t
|
|
set t [string trim $t]
|
|
set env(DYLD_LIBRARY_PATH) $t
|
|
set env(SSVNC_DYLD_LIBRARY_PATH) $t
|
|
mesg "Set DYLD_LIBRARY_PATH to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^SLEEP=} $hpt] || [regexp {^SSVNC_EXTRA_SLEEP=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*SLEEP=} $t "" t
|
|
set t [string trim $t]
|
|
set env(SSVNC_EXTRA_SLEEP) $t
|
|
mesg "Set SSVNC_EXTRA_SLEEP to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^SSH=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*SSH=} $t "" t
|
|
set t [string trim $t]
|
|
set env(SSH) $t
|
|
mesg "Set SSH to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^FINISH=} $hpt] || [regexp {^SSVNC_FINISH_SLEEP=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*=} $t "" t
|
|
set t [string trim $t]
|
|
set env(SSVNC_FINISH_SLEEP) $t
|
|
mesg "Set SSVNC_FINISH_SLEEP to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^NO_DELETE=} $hpt] || [regexp {^SSVNC_NO_DELETE=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*=} $t "" t
|
|
set t [string trim $t]
|
|
set env(SSVNC_NO_DELETE) $t
|
|
mesg "Set SSVNC_NO_DELETE to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^BAT_SLEEP=} $hpt] || [regexp {^SSVNC_BAT_SLEEP=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*=} $t "" t
|
|
set t [string trim $t]
|
|
set env(SSVNC_BAT_SLEEP) $t
|
|
mesg "Set SSVNC_BAT_SLEEP to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^DEBUG_NETSTAT=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*DEBUG_NETSTAT=} $t "" t
|
|
global debug_netstat
|
|
set debug_netstat $t
|
|
mesg "Set DEBUG_NETSTAT to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^REPEATER_FORCE=} $hpt]} {
|
|
set t $hpt
|
|
regsub {^.*REPEATER_FORCE=} $t "" t
|
|
set env(REPEATER_FORCE) $t
|
|
mesg "Set REPEATER_FORCE to $t"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp -nocase {^SSH.?ONLY} $hpt]} {
|
|
global ssh_only
|
|
if {$ssh_only} {
|
|
return 0;
|
|
}
|
|
to_sshonly
|
|
|
|
return 0
|
|
}
|
|
if {[regexp -nocase {^TS.?ONLY} $hpt]} {
|
|
global ts_only
|
|
if {$ts_only} {
|
|
return 0;
|
|
}
|
|
to_tsonly
|
|
|
|
return 0
|
|
}
|
|
if {[regexp -nocase {^IPV6=([01])} $hpt mv val]} {
|
|
global env have_ipv6
|
|
set have_ipv6 $val
|
|
set env(SSVNC_IPV6) $val
|
|
mesg "Set have_ipv6 to $val"
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
if {[regexp {^ENV=([A-z0-9][A-z0-9]*)=(.*)$} $hpt mv var val]} {
|
|
global env
|
|
if {$val == ""} {
|
|
catch {unset env($var)}
|
|
mesg "Unset $var"
|
|
} else {
|
|
set env($var) "$val"
|
|
mesg "Set $var to $val"
|
|
}
|
|
set vncdisplay ""
|
|
return 0
|
|
}
|
|
|
|
regsub {[ ]*cmd=.*$} $hp "" tt
|
|
|
|
if {[regexp {^[ ]*$} $tt]} {
|
|
mesg "No host:disp supplied."
|
|
bell
|
|
catch {raise .}
|
|
mac_raise
|
|
return
|
|
}
|
|
if {[regexp -- {--nohost--} $tt]} {
|
|
mesg "No host:disp supplied."
|
|
bell
|
|
catch {raise .}
|
|
mac_raise
|
|
return
|
|
}
|
|
# XXX host_part
|
|
if {! [regexp ":" $hp]} {
|
|
if {! [regexp {cmd=} $hp]} {
|
|
set s [string trim $hp]
|
|
if {! [regexp { } $s]} {
|
|
append hp ":0"
|
|
} else {
|
|
regsub { } $hp ":0 " hp
|
|
}
|
|
}
|
|
}
|
|
|
|
if {!$use_ssl && !$use_ssh && !$use_sshssl && $sshssl_sw == "none"} {
|
|
regsub -nocase {^[a-z0-9+]*://} $hp "" hp
|
|
set hp "Vnc://$hp"
|
|
}
|
|
|
|
mesg "Using: $hp"
|
|
after 600
|
|
|
|
set sc [get_ssh_cmd $hp]
|
|
if {[regexp {^KNOCK} $sc]} {
|
|
if [regexp {^KNOCKF} $sc] {
|
|
port_knock_only $hp "FINISH"
|
|
} else {
|
|
port_knock_only $hp "KNOCK"
|
|
}
|
|
return
|
|
}
|
|
|
|
if {$debug} {
|
|
mesg "\"$tcl_platform(os)\" | \"$tcl_platform(osVersion)\""
|
|
after 1000
|
|
}
|
|
|
|
if [regexp {V[Nn][Cc]://} $hp] {
|
|
set env(SSVNC_NO_ENC_WARN) 1
|
|
regsub {V[Nn][Cc]://} $hp "vnc://" hp
|
|
}
|
|
regsub -nocase {^vnc://} $hp "vnc://" hp
|
|
regsub -nocase {^vncs://} $hp "vncs://" hp
|
|
regsub -nocase {^vncssl://} $hp "vncssl://" hp
|
|
regsub -nocase {^vnc\+ssl://} $hp "vnc+ssl://" hp
|
|
regsub -nocase {^vncssh://} $hp "vncssh://" hp
|
|
regsub -nocase {^vnc\+ssh://} $hp "vnc+ssh://" hp
|
|
|
|
if {! $is_windows} {
|
|
launch_unix $hp
|
|
return
|
|
}
|
|
|
|
##############################################################
|
|
# WINDOWS BELOW:
|
|
|
|
if [regexp {^vnc://} $hp] {
|
|
if {! [info exists env(SSVNC_NO_ENC_WARN)]} {
|
|
direct_connect_msg
|
|
}
|
|
regsub {^vnc://} $hp "" hp
|
|
direct_connect_windows $hp
|
|
return
|
|
} elseif [regexp {^vncs://} $hp] {
|
|
set use_ssl 1
|
|
set use_ssh 0
|
|
regsub {^vncs://} $hp "" hp
|
|
sync_use_ssl_ssh
|
|
} elseif [regexp {^vncssl://} $hp] {
|
|
set use_ssl 1
|
|
set use_ssh 0
|
|
regsub {^vncssl://} $hp "" hp
|
|
sync_use_ssl_ssh
|
|
} elseif [regexp {^vnc\+ssl://} $hp] {
|
|
set use_ssl 1
|
|
set use_ssh 0
|
|
regsub {^vnc\+ssl://} $hp "" hp
|
|
sync_use_ssl_ssh
|
|
} elseif [regexp {^vncssh://} $hp] {
|
|
set use_ssh 1
|
|
set use_ssl 0
|
|
regsub {vncssh://} $hp "" hp
|
|
sync_use_ssl_ssh
|
|
} elseif [regexp {^vnc\+ssh://} $hp] {
|
|
set use_ssh 1
|
|
set use_ssl 0
|
|
regsub {^vnc\+ssh://} $hp "" hp
|
|
sync_use_ssl_ssh
|
|
}
|
|
|
|
check_ssh_needed
|
|
|
|
if {! $use_ssh} {
|
|
if {$mycert != ""} {
|
|
if {! [file exists $mycert]} {
|
|
mesg "MyCert does not exist: $mycert"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
if {$svcert != ""} {
|
|
if {! [file exists $svcert]} {
|
|
mesg "ServerCert does not exist: $svcert"
|
|
bell
|
|
return
|
|
}
|
|
} elseif {$crtdir != ""} {
|
|
if {! [file exists $crtdir] && $crtdir != "ACCEPTED_CERTS"} {
|
|
mesg "CertsDir does not exist: $crtdir"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
if {$crlfil != ""} {
|
|
if {! [file exists $crlfil]} {
|
|
mesg "CRL File does not exist: $crlfil"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
# VF
|
|
set prefix "stunnel-vnc"
|
|
set suffix "conf"
|
|
if {$use_ssh || $use_sshssl} {
|
|
set prefix "plink_vnc"
|
|
set suffix "bat"
|
|
}
|
|
|
|
set file1 ""
|
|
set n1 ""
|
|
set file2 ""
|
|
set n2 ""
|
|
set n3 ""
|
|
set n4 ""
|
|
set now [clock seconds]
|
|
|
|
set proxy [get_ssh_proxy $hp]
|
|
if {$use_sshssl} {
|
|
set proxy ""
|
|
}
|
|
if {! [repeater_proxy_check $proxy]} {
|
|
return
|
|
}
|
|
|
|
global port_slot
|
|
if {$port_slot != ""} {
|
|
set file1 "$prefix-$port_slot.$suffix"
|
|
set n1 $port_slot
|
|
set ps [expr $port_slot + 200]
|
|
set file2 "$prefix-$ps.$suffix"
|
|
set n2 $ps
|
|
mesg "Using Port Slot: $port_slot"
|
|
after 700
|
|
}
|
|
|
|
for {set i 30} {$i <= 99} {incr i} {
|
|
set try "$prefix-$i.$suffix"
|
|
if {$i == $port_slot} {
|
|
continue
|
|
}
|
|
if {[file exists $try]} {
|
|
set mt [file mtime $try]
|
|
set age [expr "$now - $mt"]
|
|
set week [expr "7 * 3600 * 24"]
|
|
if {$age > $week} {
|
|
catch {file delete $try}
|
|
}
|
|
}
|
|
if {! [file exists $try]} {
|
|
if {$file1 == ""} {
|
|
set file1 $try
|
|
set n1 $i
|
|
} elseif {$file2 == ""} {
|
|
set file2 $try
|
|
set n2 $i
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if {$file1 == ""} {
|
|
mesg "could not find free stunnel file"
|
|
bell
|
|
return
|
|
}
|
|
|
|
if {$n1 == ""} {
|
|
set n1 10
|
|
}
|
|
if {$n2 == ""} {
|
|
set n2 11
|
|
}
|
|
set n3 [expr $n1 + 100]
|
|
set n4 [expr $n2 + 100]
|
|
|
|
global launch_windows_ssh_files
|
|
set launch_windows_ssh_files ""
|
|
|
|
set did_port_knock 0
|
|
|
|
global listening_name
|
|
set listening_name ""
|
|
|
|
if {$use_ssh} {
|
|
;
|
|
} elseif {$use_sshssl} {
|
|
;
|
|
} elseif {$use_ssl} {
|
|
if {$proxy != "" && [regexp {@} $proxy]} {
|
|
mesg "Error: proxy contains '@' Did you mean to use SSH mode?"
|
|
bell
|
|
return
|
|
}
|
|
if [regexp {@} $hp] {
|
|
mesg "Error: host contains '@' Did you mean to use SSH mode?"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
|
|
global ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
|
|
if {$use_sshssl} {
|
|
set rc [launch_windows_ssh $hp $file2 $n2]
|
|
if {$rc == 0} {
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
catch {file delete $file1}
|
|
catch {file delete $file2}
|
|
}
|
|
del_launch_windows_ssh_files
|
|
return
|
|
}
|
|
set did_port_knock 1
|
|
} elseif {$use_ssh} {
|
|
launch_windows_ssh $hp $file1 $n1
|
|
# WE ARE DONE.
|
|
return
|
|
}
|
|
|
|
set host [host_part $hp];
|
|
set host_orig $host
|
|
|
|
global win_localhost
|
|
|
|
if {$host == ""} {
|
|
set host $win_localhost
|
|
}
|
|
|
|
if [regexp {^.*@} $host match] {
|
|
catch {raise .; update}
|
|
mesg "Trimming \"$match\" from hostname"
|
|
after 700
|
|
regsub {^.*@} $host "" host
|
|
}
|
|
|
|
set disp [port_part $hp]
|
|
if {[regexp {^-[0-9][0-9]*$} $disp]} {
|
|
;
|
|
} elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
|
|
set disp 0
|
|
}
|
|
|
|
if {$disp < 0} {
|
|
set port [expr "- $disp"]
|
|
} elseif {$disp < 200} {
|
|
if {$use_listen} {
|
|
set port [expr "$disp + 5500"]
|
|
} else {
|
|
set port [expr "$disp + 5900"]
|
|
}
|
|
} else {
|
|
set port $disp
|
|
}
|
|
|
|
if {$debug} {
|
|
mesg "file: $file1"
|
|
after 1000
|
|
}
|
|
|
|
listen_verify_all_dialog $hp
|
|
|
|
if {$use_listen && $mycert == ""} {
|
|
if {! [check_for_listen_ssl_cert]} {
|
|
return;
|
|
}
|
|
}
|
|
|
|
set fail 0
|
|
|
|
set fh [open $file1 "w"]
|
|
|
|
if {$use_listen} {
|
|
puts $fh "client = no"
|
|
} else {
|
|
puts $fh "client = yes"
|
|
}
|
|
global disable_ssl_workarounds disable_ssl_workarounds_type
|
|
if {$disable_ssl_workarounds} {
|
|
if {$disable_ssl_workarounds_type == "noempty"} {
|
|
puts $fh "options = DONT_INSERT_EMPTY_FRAGMENTS"
|
|
}
|
|
} else {
|
|
puts $fh "options = ALL"
|
|
}
|
|
|
|
puts $fh "taskbar = yes"
|
|
puts $fh "RNDbytes = 2048"
|
|
puts $fh "RNDfile = bananarand.bin"
|
|
puts $fh "RNDoverwrite = yes"
|
|
puts $fh "debug = 6"
|
|
|
|
if {$mycert != ""} {
|
|
if {! [file exists $mycert]} {
|
|
mesg "MyCert does not exist: $mycert"
|
|
bell
|
|
set fail 1
|
|
}
|
|
puts $fh "cert = $mycert"
|
|
} elseif {$use_listen} {
|
|
# see above, this should not happen.
|
|
puts $fh "cert = _nocert_"
|
|
}
|
|
if {$crlfil != ""} {
|
|
if [file isdirectory $crlfil] {
|
|
puts $fh "CRLpath = $crlfil"
|
|
} else {
|
|
puts $fh "CRLfile = $crlfil"
|
|
}
|
|
}
|
|
|
|
set did_check 0
|
|
|
|
if {$svcert != ""} {
|
|
if {! [file exists $svcert]} {
|
|
mesg "ServerCert does not exist: $svcert"
|
|
bell
|
|
set fail 1
|
|
}
|
|
puts $fh "CAfile = $svcert"
|
|
puts $fh "verify = 2"
|
|
} elseif {$crtdir != ""} {
|
|
if {$crtdir == "ACCEPTED_CERTS"} {
|
|
global skip_verify_accepted_certs
|
|
set skip_verify_accepted_certs 0
|
|
set did_check 1
|
|
if {$use_sshssl} {
|
|
set skip_verify_accepted_certs 1
|
|
set did_check 0
|
|
} elseif {! [check_accepted_certs 0]} {
|
|
set fail 1
|
|
}
|
|
if {! $skip_verify_accepted_certs} {
|
|
set adir [get_idir_certs ""]
|
|
set adir "$adir/accepted"
|
|
catch {file mkdir $adir}
|
|
puts $fh "CApath = $adir"
|
|
puts $fh "verify = 2"
|
|
}
|
|
} else {
|
|
if {! [file exists $crtdir]} {
|
|
mesg "CertsDir does not exist: $crtdir"
|
|
bell
|
|
set fail 1
|
|
}
|
|
puts $fh "CApath = $crtdir"
|
|
puts $fh "verify = 2"
|
|
}
|
|
}
|
|
|
|
if {!$did_check} {
|
|
check_accepted_certs 1
|
|
}
|
|
|
|
if {$use_sshssl} {
|
|
set p [expr "$n2 + 5900"]
|
|
set proxy [maybe_add_vencrypt $proxy "$win_localhost:$p"]
|
|
} else {
|
|
set proxy [maybe_add_vencrypt $proxy $hp]
|
|
}
|
|
|
|
set ipv6_pid ""
|
|
global have_ipv6
|
|
if {$have_ipv6} {
|
|
if {$proxy == "" && $use_ssl} {
|
|
# stunnel can handle ipv6
|
|
} else {
|
|
set res [ipv6_proxy $proxy $host $port]
|
|
set proxy [lindex $res 0]
|
|
set host [lindex $res 1]
|
|
set port [lindex $res 2]
|
|
set ipv6_pid [lindex $res 3]
|
|
}
|
|
}
|
|
|
|
set p_reverse 0
|
|
|
|
if {$proxy != ""} {
|
|
if {$use_sshssl} {
|
|
;
|
|
} elseif [regexp {@} $proxy] {
|
|
bell
|
|
catch {raise .; update}
|
|
mesg "WARNING: SSL proxy contains \"@\" sign"
|
|
after 1500
|
|
}
|
|
set env(SSVNC_PROXY) $proxy
|
|
set env(SSVNC_DEST) "$host:$port"
|
|
if {$use_listen} {
|
|
set env(SSVNC_REVERSE) "$win_localhost:$port"
|
|
set env(CONNECT_BR_SLEEP) 3
|
|
set p_reverse 1
|
|
} else {
|
|
if {$use_sshssl && [regexp {vencrypt:} $proxy]} {
|
|
set env(SSVNC_LISTEN) [expr "$n4 + 5900"]
|
|
} else {
|
|
set env(SSVNC_LISTEN) [expr "$n2 + 5900"]
|
|
}
|
|
}
|
|
if {[info exists env(PROXY_DEBUG)]} {
|
|
foreach var [list SSVNC_PROXY SSVNC_DEST SSVNC_REVERSE CONNECT_BR_SLEEP SSVNC_LISTEN] {
|
|
if [info exists env($var)] {
|
|
mesg "$var $env($var)"; after 2500;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
global anon_dh_detected server_anondh
|
|
if {$anon_dh_detected || $server_anondh} {
|
|
puts $fh "ciphers = ALL:RC4+RSA:+SSLv2:@STRENGTH"
|
|
set anon_dh_detected 0
|
|
}
|
|
|
|
|
|
puts $fh "\[vnc$n1\]"
|
|
set port2 ""
|
|
set port3 ""
|
|
if {! $use_listen} {
|
|
set port2 [expr "$n1 + 5900"]
|
|
if [regexp {vencrypt:} $proxy] {
|
|
set port3 [expr "$n3 + 5900"]
|
|
set port2 $port3
|
|
puts $fh "accept = $win_localhost:$port3"
|
|
} else {
|
|
puts $fh "accept = $win_localhost:$port2"
|
|
}
|
|
|
|
if {$use_sshssl && [regexp {vencrypt:} $proxy]} {
|
|
set port [expr "$n4 + 5900"]
|
|
puts $fh "connect = $win_localhost:$port"
|
|
} elseif {$use_sshssl || $proxy != ""} {
|
|
set port [expr "$n2 + 5900"]
|
|
puts $fh "connect = $win_localhost:$port"
|
|
} else {
|
|
puts $fh "connect = $host:$port"
|
|
}
|
|
} else {
|
|
set port2 [expr "$n1 + 5500"]
|
|
set hloc ""
|
|
if {$use_ssh} {
|
|
# not reached?
|
|
set hloc "$win_localhost:"
|
|
set listening_name "$win_localhost:$port (on remote SSH side)"
|
|
} else {
|
|
set hn [get_hostname]
|
|
if {$hn == ""} {
|
|
set hn "this-computer"
|
|
}
|
|
set listening_name "$hn:$port (or nn.nn.nn.nn:$port, etc.)"
|
|
}
|
|
if {$host_orig != "" && $hloc == ""} {
|
|
set hloc "$host_orig:"
|
|
}
|
|
puts $fh "accept = $hloc$port"
|
|
puts $fh "connect = $win_localhost:$port2"
|
|
}
|
|
|
|
puts $fh "delay = no"
|
|
puts $fh ""
|
|
close $fh
|
|
|
|
if {! $did_port_knock} {
|
|
if {! [do_port_knock $host start]} {
|
|
set fail 1
|
|
}
|
|
set did_port_knock 1
|
|
}
|
|
|
|
if {$fail} {
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
catch {file delete $file1}
|
|
}
|
|
catch { unset env(SSVNC_PROXY) }
|
|
catch { unset env(SSVNC_LISTEN) }
|
|
catch { unset env(SSVNC_REVERSE) }
|
|
catch { unset env(SSVNC_DEST) }
|
|
catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) }
|
|
catch { unset env(CONNECT_BR_SLEEP) }
|
|
winkill $ipv6_pid
|
|
winkill $ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
return
|
|
}
|
|
|
|
note_stunnel_pids "before"
|
|
|
|
set proxy_pid ""
|
|
set proxy_pid2 ""
|
|
|
|
if {$use_listen} {
|
|
windows_listening_message $n1
|
|
}
|
|
|
|
if {$proxy != ""} {
|
|
if [regexp {vencrypt:} $proxy] {
|
|
set vport [expr "$n1 + 5900"]
|
|
mesg "Starting VeNCrypt helper on port $vport,$port3 ..."
|
|
after 500
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
catch {file delete "$file1.pre"}
|
|
}
|
|
set env(SSVNC_PREDIGESTED_HANDSHAKE) "$file1.pre"
|
|
set env(SSVNC_VENCRYPT_VIEWER_BRIDGE) "$vport,$port3"
|
|
set proxy_pid2 [exec "connect_br.exe" &]
|
|
catch { unset env(SSVNC_VENCRYPT_VIEWER_BRIDGE) }
|
|
}
|
|
mesg "Starting TCP helper on port $port ..."
|
|
after 400
|
|
# ssl br case:
|
|
set proxy_pid [exec "connect_br.exe" &]
|
|
catch { unset env(SSVNC_PROXY) }
|
|
catch { unset env(SSVNC_LISTEN) }
|
|
catch { unset env(SSVNC_REVERSE) }
|
|
catch { unset env(SSVNC_DEST) }
|
|
catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) }
|
|
catch { unset env(CONNECT_BR_SLEEP) }
|
|
}
|
|
|
|
mesg "Starting STUNNEL on port $port2 ..."
|
|
after 500
|
|
|
|
set pids [exec stunnel $file1 &]
|
|
|
|
if {! $p_reverse} {
|
|
after 300
|
|
set vtm [vencrypt_tutorial_mesg]
|
|
if {$vtm == ""} {
|
|
after 300
|
|
}
|
|
}
|
|
|
|
note_stunnel_pids "after"
|
|
|
|
if {$debug} {
|
|
after 1000
|
|
mesg "pids $pids"
|
|
after 1000
|
|
} else {
|
|
catch {destroy .o}
|
|
catch {destroy .oa}
|
|
catch {destroy .os}
|
|
wm withdraw .
|
|
}
|
|
|
|
do_viewer_windows $n1
|
|
|
|
del_launch_windows_ssh_files
|
|
|
|
if {![info exists env(SSVNC_NO_DELETE)]} {
|
|
catch {file delete $file1}
|
|
}
|
|
|
|
if {$debug} {
|
|
;
|
|
} else {
|
|
wm deiconify .
|
|
}
|
|
mesg "Disconnected from $hp."
|
|
|
|
global port_knocking_list
|
|
if [regexp {FINISH} $port_knocking_list] {
|
|
do_port_knock $host finish
|
|
}
|
|
|
|
if {[llength $pids_new] > 0} {
|
|
set plist [join $pids_new ", "]
|
|
global terminate_pids
|
|
set terminate_pids ""
|
|
global kill_stunnel
|
|
if {$kill_stunnel} {
|
|
set terminate_pids yes
|
|
} else {
|
|
win_kill_msg $plist
|
|
update
|
|
vwait terminate_pids
|
|
}
|
|
if {$terminate_pids == "yes"} {
|
|
kill_stunnel $pids_new
|
|
}
|
|
} else {
|
|
win_nokill_msg
|
|
}
|
|
mesg "Disconnected from $hp."
|
|
winkill $ipv6_pid
|
|
winkill $ssh_ipv6_pid
|
|
set ssh_ipv6_pid ""
|
|
|
|
global is_win9x use_sound sound_daemon_local_kill sound_daemon_local_cmd
|
|
if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
|
|
windows_stop_sound_daemon
|
|
}
|
|
}
|
|
|
|
proc direct_connect_windows {{hp ""}} {
|
|
global tcl_platform is_windows
|
|
global env use_listen
|
|
|
|
set proxy [get_ssh_proxy $hp]
|
|
|
|
set did_port_knock 0
|
|
|
|
global listening_name
|
|
set listening_name ""
|
|
|
|
set host [host_part $hp]
|
|
|
|
set host_orig $host
|
|
|
|
global win_localhost
|
|
if {$host == ""} {
|
|
set host $win_localhost
|
|
}
|
|
|
|
if [regexp {^.*@} $host match] {
|
|
catch {raise .; update}
|
|
mesg "Trimming \"$match\" from hostname"
|
|
after 700
|
|
regsub {^.*@} $host "" host
|
|
}
|
|
|
|
set disp [port_part $hp]
|
|
if {[regexp {^-[0-9][0-9]*$} $disp]} {
|
|
;
|
|
} elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
|
|
set disp 0
|
|
}
|
|
|
|
if {$disp < 0} {
|
|
set port [expr "- $disp"]
|
|
} elseif {$disp < 200} {
|
|
if {$use_listen} {
|
|
set port [expr "$disp + 5500"]
|
|
} else {
|
|
set port [expr "$disp + 5900"]
|
|
}
|
|
} else {
|
|
set port $disp
|
|
}
|
|
|
|
global have_ipv6
|
|
set ipv6_pid ""
|
|
if {$have_ipv6 && !$use_listen} {
|
|
set res [ipv6_proxy $proxy $host $port]
|
|
set proxy [lindex $res 0]
|
|
set host [lindex $res 1]
|
|
set port [lindex $res 2]
|
|
set ipv6_pid [lindex $res 3]
|
|
}
|
|
|
|
if {$proxy != ""} {
|
|
if [regexp {@} $proxy] {
|
|
bell
|
|
catch {raise .; update}
|
|
mesg "WARNING: SSL proxy contains \"@\" sign"
|
|
after 1500
|
|
}
|
|
set n2 45
|
|
|
|
set env(SSVNC_PROXY) $proxy
|
|
set env(SSVNC_LISTEN) [expr "$n2 + 5900"]
|
|
set env(SSVNC_DEST) "$host:$port"
|
|
|
|
set port [expr $n2 + 5900]
|
|
set host $win_localhost
|
|
}
|
|
|
|
set fail 0
|
|
if {! $did_port_knock} {
|
|
if {! [do_port_knock $host start]} {
|
|
set fail 1
|
|
}
|
|
set did_port_knock 1
|
|
}
|
|
|
|
if {$fail} {
|
|
catch { unset env(SSVNC_PROXY) }
|
|
catch { unset env(SSVNC_LISTEN) }
|
|
catch { unset env(SSVNC_DEST) }
|
|
winkill $ipv6_pid
|
|
return
|
|
}
|
|
|
|
set proxy_pid ""
|
|
if {$proxy != ""} {
|
|
mesg "Starting Proxy TCP helper on port $port ..."
|
|
after 400
|
|
# unencrypted br case:
|
|
set proxy_pid [exec "connect_br.exe" &]
|
|
catch { unset env(SSVNC_PROXY) }
|
|
catch { unset env(SSVNC_LISTEN) }
|
|
catch { unset env(SSVNC_DEST) }
|
|
}
|
|
|
|
vencrypt_tutorial_mesg
|
|
|
|
catch {destroy .o}
|
|
catch {destroy .oa}
|
|
catch {destroy .os}
|
|
wm withdraw .
|
|
|
|
if {$use_listen} {
|
|
set n $port
|
|
if {$n >= 5500} {
|
|
set n [expr $n - 5500]
|
|
}
|
|
global direct_connect_reverse_host_orig
|
|
set direct_connect_reverse_host_orig $host_orig
|
|
|
|
do_viewer_windows "$n"
|
|
|
|
set direct_connect_reverse_host_orig ""
|
|
} else {
|
|
if {$port >= 5900 && $port < 6100} {
|
|
set port [expr $port - 5900]
|
|
}
|
|
do_viewer_windows "$host:$port"
|
|
}
|
|
|
|
wm deiconify .
|
|
|
|
mesg "Disconnected from $hp."
|
|
|
|
winkill $ipv6_pid
|
|
|
|
global port_knocking_list
|
|
if [regexp {FINISH} $port_knocking_list] {
|
|
do_port_knock $host finish
|
|
}
|
|
|
|
mesg "Disconnected from $hp."
|
|
}
|
|
|
|
proc get_idir_certs {str} {
|
|
global is_windows env
|
|
set idir ""
|
|
if {$str != ""} {
|
|
if [file isdirectory $str] {
|
|
set idir $str
|
|
} else {
|
|
set idir [file dirname $str]
|
|
}
|
|
if {$is_windows} {
|
|
regsub -all {\\} $idir "/" idir
|
|
regsub -all {//*} $idir "/" idir
|
|
}
|
|
}
|
|
if {$idir == ""} {
|
|
if {$is_windows} {
|
|
if [info exists env(SSVNC_HOME)] {
|
|
set t "$env(SSVNC_HOME)/ss_vnc"
|
|
regsub -all {\\} $t "/" t
|
|
regsub -all {//*} $t "/" t
|
|
if {! [file isdirectory $t]} {
|
|
catch {file mkdir $t}
|
|
}
|
|
set t "$env(SSVNC_HOME)/ss_vnc/certs"
|
|
regsub -all {\\} $t "/" t
|
|
regsub -all {//*} $t "/" t
|
|
if {! [file isdirectory $t]} {
|
|
catch {file mkdir $t}
|
|
}
|
|
if [file isdirectory $t] {
|
|
set idir $t
|
|
}
|
|
}
|
|
if {$idir == ""} {
|
|
set t [file dirname [pwd]]
|
|
set t "$t/certs"
|
|
if [file isdirectory $t] {
|
|
set idir $t
|
|
}
|
|
}
|
|
}
|
|
if {$idir == ""} {
|
|
if [info exists env(SSVNC_HOME)] {
|
|
set t "$env(SSVNC_HOME)/.vnc"
|
|
if {! [file isdirectory $t]} {
|
|
catch {file mkdir $t}
|
|
}
|
|
set t "$env(SSVNC_HOME)/.vnc/certs"
|
|
if {! [file isdirectory $t]} {
|
|
catch {file mkdir $t}
|
|
}
|
|
if [file isdirectory $t] {
|
|
set idir $t
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if {$idir == ""} {
|
|
if {$is_windows} {
|
|
set idir [get_profiles_dir]
|
|
}
|
|
if {$idir == ""} {
|
|
set idir [pwd]
|
|
}
|
|
}
|
|
return $idir
|
|
}
|
|
|
|
proc delete_cert {{parent "."}} {
|
|
set idir [get_idir_certs ""]
|
|
set f ""
|
|
unix_dialog_resize $parent
|
|
if {$idir != ""} {
|
|
set f [tk_getOpenFile -parent $parent -initialdir $idir]
|
|
} else {
|
|
set f [tk_getOpenFile -parent $parent]
|
|
}
|
|
if {$f != "" && [file exists $f]} {
|
|
set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f"]
|
|
if {$reply == "yes"} {
|
|
global mycert svcert crlfil
|
|
set f_text [read_file $f]
|
|
set f2 ""
|
|
catch {file delete $f}
|
|
if {$f == $mycert} { set mycert "" }
|
|
if {$f == $svcert} { set svcert "" }
|
|
if {$f == $crlfil} { set crlfil "" }
|
|
if [regexp {\.crt$} $f] {
|
|
regsub {\.crt$} $f ".pem" f2
|
|
} elseif [regexp {\.pem$} $f] {
|
|
regsub {\.pem$} $f ".crt" f2
|
|
}
|
|
if {$f2 != "" && [file exists $f2]} {
|
|
set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f2"]
|
|
if {$reply == "yes"} {
|
|
catch {file delete $f2}
|
|
if {$f2 == $mycert} { set mycert "" }
|
|
if {$f2 == $svcert} { set svcert "" }
|
|
if {$f2 == $crlfil} { set crlfil "" }
|
|
}
|
|
}
|
|
set dir [file dirname $f]
|
|
if {$f_text != "" && [regexp {accepted$} $dir]} {
|
|
foreach crt [glob -nocomplain -directory $dir {*.crt} {*.pem} {*.[0-9]}] {
|
|
#puts "try $crt"
|
|
set c_text [read_file $crt]
|
|
if {$c_text == ""} {
|
|
continue
|
|
}
|
|
if {$c_text != $f_text} {
|
|
continue
|
|
}
|
|
set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Identical Cert" -message "Delete Identical $crt"]
|
|
if {$reply == "yes"} {
|
|
catch {file delete $crt}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch {wm deiconify .c}
|
|
update
|
|
}
|
|
|
|
proc set_mycert {{parent "."}} {
|
|
global mycert
|
|
set idir [get_idir_certs $mycert]
|
|
set t ""
|
|
unix_dialog_resize $parent
|
|
if {$idir != ""} {
|
|
set t [tk_getOpenFile -parent $parent -initialdir $idir]
|
|
} else {
|
|
set t [tk_getOpenFile -parent $parent]
|
|
}
|
|
if {$t != ""} {
|
|
set mycert $t
|
|
}
|
|
catch {wm deiconify .c}
|
|
v_mycert
|
|
update
|
|
}
|
|
|
|
proc set_crlfil {{parent "."}} {
|
|
global crlfil
|
|
set idir [get_idir_certs $crlfil]
|
|
set t ""
|
|
unix_dialog_resize $parent
|
|
if {$idir != ""} {
|
|
set t [tk_getOpenFile -parent $parent -initialdir $idir]
|
|
} else {
|
|
set t [tk_getOpenFile -parent $parent]
|
|
}
|
|
if {$t != ""} {
|
|
set crlfil $t
|
|
}
|
|
catch {wm deiconify .c}
|
|
v_crlfil
|
|
update
|
|
}
|
|
|
|
proc set_ultra_dsm_file {{parent "."}} {
|
|
global ultra_dsm_file
|
|
set idir [get_idir_certs $ultra_dsm_file]
|
|
set t ""
|
|
unix_dialog_resize $parent
|
|
if {$idir != ""} {
|
|
set t [tk_getOpenFile -parent $parent -initialdir $idir]
|
|
} else {
|
|
set t [tk_getOpenFile -parent $parent]
|
|
}
|
|
if {$t != ""} {
|
|
set ultra_dsm_file $t
|
|
}
|
|
update
|
|
}
|
|
|
|
proc set_ssh_known_hosts_file {{parent "."}} {
|
|
global ssh_known_hosts_filename is_windows uname
|
|
|
|
if {$ssh_known_hosts_filename == ""} {
|
|
set pdir [get_profiles_dir]
|
|
set pdir "$pdir/ssh_known_hosts"
|
|
catch {file mkdir $pdir}
|
|
|
|
global last_load
|
|
if {![info exists last_load]} {
|
|
set last_load ""
|
|
}
|
|
if {$last_load != ""} {
|
|
set dispf [string trim $last_load]
|
|
set dispf [file tail $dispf]
|
|
|
|
regsub {\.vnc$} $dispf "" dispf
|
|
if {![regexp {\.known$} $dispf]} {
|
|
set dispf "$dispf.known"
|
|
}
|
|
set guess $dispf
|
|
} else {
|
|
set vncdisp [get_vncdisplay]
|
|
set dispf [string trim $vncdisp]
|
|
if {$dispf != ""} {
|
|
regsub {[ ].*$} $dispf "" dispf
|
|
regsub -all {/} $dispf "" dispf
|
|
} else {
|
|
set dispf "unique-name-here"
|
|
}
|
|
if {$is_windows || $uname == "Darwin"} {
|
|
regsub -all {:} $dispf "-" dispf
|
|
} else {
|
|
regsub -all {:} $dispf "-" dispf
|
|
}
|
|
if {![regexp {\.known$} $dispf]} {
|
|
set dispf "$dispf.known"
|
|
}
|
|
set guess $dispf
|
|
}
|
|
} else {
|
|
set pdir [file dirname $ssh_known_hosts_filename]
|
|
set guess [file tail $ssh_known_hosts_filename]
|
|
}
|
|
|
|
set t ""
|
|
unix_dialog_resize $parent
|
|
if {$pdir != ""} {
|
|
set t [tk_getSaveFile -parent $parent -initialdir $pdir -initialfile $guess]
|
|
} else {
|
|
set t [tk_getSaveFile -parent $parent -initialfile $guess]
|
|
}
|
|
if {$t != ""} {
|
|
set ssh_known_hosts_filename $t
|
|
}
|
|
update
|
|
}
|
|
|
|
proc show_cert {crt} {
|
|
if {$crt == ""} {
|
|
bell
|
|
return
|
|
}
|
|
if {! [file exists $crt]} {
|
|
bell
|
|
return
|
|
}
|
|
set info ""
|
|
catch {set info [get_x509_info $crt]}
|
|
if {$info == ""} {
|
|
bell
|
|
return
|
|
}
|
|
|
|
set w .show_certificate
|
|
toplev $w
|
|
scroll_text $w.f
|
|
button $w.b -text Dismiss -command "destroy $w"
|
|
bind $w <Escape> "destroy $w"
|
|
$w.f.t insert end $info
|
|
|
|
pack $w.b -side bottom -fill x
|
|
pack $w.f -side top -fill both -expand 1
|
|
center_win $w
|
|
catch {raise $w}
|
|
}
|
|
|
|
proc show_crl {crl} {
|
|
if {$crl == ""} {
|
|
bell
|
|
return
|
|
}
|
|
if {! [file exists $crl]} {
|
|
bell
|
|
return
|
|
}
|
|
|
|
set flist [list]
|
|
|
|
if [file isdirectory $crl] {
|
|
foreach cfile [glob -nocomplain -directory $crl "*"] {
|
|
if [file isfile $cfile] {
|
|
lappend flist $cfile
|
|
}
|
|
}
|
|
} else {
|
|
lappend flist $crl
|
|
}
|
|
|
|
set ossl [get_openssl]
|
|
set info ""
|
|
|
|
foreach cfile $flist {
|
|
catch {
|
|
set ph [open "| $ossl crl -fingerprint -text -noout -in \"$cfile\"" "r"]
|
|
while {[gets $ph line] > -1} {
|
|
append info "$line\n"
|
|
}
|
|
close $ph
|
|
append info "\n"
|
|
}
|
|
}
|
|
|
|
set w .show_crl
|
|
toplev $w
|
|
scroll_text $w.f
|
|
button $w.b -text Dismiss -command "destroy $w"
|
|
bind $w <Escape> "destroy $w"
|
|
$w.f.t insert end $info
|
|
|
|
pack $w.b -side bottom -fill x
|
|
pack $w.f -side top -fill both -expand 1
|
|
center_win $w
|
|
catch {raise $w}
|
|
}
|
|
|
|
proc v_svcert {} {
|
|
global svcert
|
|
if {$svcert == "" || ! [file exists $svcert]} {
|
|
catch {.c.svcert.i configure -state disabled}
|
|
} else {
|
|
catch {.c.svcert.i configure -state normal}
|
|
}
|
|
no_certs_tutorial_mesg
|
|
return 1
|
|
}
|
|
|
|
proc v_mycert {} {
|
|
global mycert
|
|
if {$mycert == "" || ! [file exists $mycert]} {
|
|
catch {.c.mycert.i configure -state disabled}
|
|
} else {
|
|
catch {.c.mycert.i configure -state normal}
|
|
}
|
|
return 1
|
|
}
|
|
|
|
proc v_crlfil {} {
|
|
global crlfil
|
|
if {$crlfil == "" || ! [file exists $crlfil]} {
|
|
catch {.c.crlfil.i configure -state disabled}
|
|
} else {
|
|
catch {.c.crlfil.i configure -state normal}
|
|
}
|
|
return 1
|
|
}
|
|
|
|
proc show_mycert {} {
|
|
global mycert
|
|
show_cert $mycert
|
|
}
|
|
|
|
proc show_svcert {} {
|
|
global svcert
|
|
show_cert $svcert
|
|
}
|
|
|
|
proc show_crlfil {} {
|
|
global crlfil
|
|
show_crl $crlfil
|
|
}
|
|
|
|
proc set_svcert {{parent "."}} {
|
|
global svcert crtdir
|
|
set idir [get_idir_certs $svcert]
|
|
set t ""
|
|
unix_dialog_resize $parent
|
|
if {$idir != ""} {
|
|
set t [tk_getOpenFile -parent $parent -initialdir $idir]
|
|
} else {
|
|
set t [tk_getOpenFile -parent $parent]
|
|
}
|
|
if {$t != ""} {
|
|
set crtdir ""
|
|
set svcert $t
|
|
}
|
|
catch {wm deiconify .c}
|
|
v_svcert
|
|
update
|
|
}
|
|
|
|
proc set_crtdir {{parent "."}} {
|
|
global svcert crtdir
|
|
set idir ""
|
|
if {$crtdir == "ACCEPTED_CERTS"} {
|
|
set idir [get_idir_certs ""]
|
|
} else {
|
|
set idir [get_idir_certs $crtdir]
|
|
}
|
|
set t ""
|
|
unix_dialog_resize $parent
|
|
if {$idir != ""} {
|
|
set t [tk_chooseDirectory -parent $parent -initialdir $idir]
|
|
} else {
|
|
set t [tk_chooseDirectory -parent $parent]
|
|
}
|
|
if {$t != ""} {
|
|
set svcert ""
|
|
set crtdir $t
|
|
}
|
|
catch {wm deiconify .c}
|
|
update
|
|
}
|
|
|
|
proc set_createcert_file {} {
|
|
global ccert
|
|
if {[info exists ccert(FILE)]} {
|
|
set idir [get_idir_certs $ccert(FILE)]
|
|
}
|
|
unix_dialog_resize .ccrt
|
|
if {$idir != ""} {
|
|
set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem" -initialdir $idir]
|
|
} else {
|
|
set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem"]
|
|
}
|
|
if {$t != ""} {
|
|
set ccert(FILE) $t
|
|
}
|
|
catch {raise .ccrt}
|
|
update
|
|
}
|
|
|
|
proc check_pp {} {
|
|
global ccert
|
|
if {$ccert(ENC)} {
|
|
catch {.ccrt.pf.e configure -state normal}
|
|
catch {focus .ccrt.pf.e}
|
|
catch {.ccrt.pf.e icursor end}
|
|
} else {
|
|
catch {.ccrt.pf.e configure -state disabled}
|
|
}
|
|
}
|
|
|
|
proc get_openssl {} {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
set ossl "openssl.exe"
|
|
} else {
|
|
set ossl "openssl"
|
|
}
|
|
}
|
|
|
|
proc get_x509_info {crt} {
|
|
set ossl [get_openssl]
|
|
set info ""
|
|
update
|
|
set ph [open "| $ossl x509 -text -fingerprint -in \"$crt\"" "r"]
|
|
while {[gets $ph line] > -1} {
|
|
append info "$line\n"
|
|
}
|
|
close $ph
|
|
return $info
|
|
}
|
|
|
|
proc do_oss_create {} {
|
|
global is_windows is_win9x
|
|
|
|
set cfg {
|
|
[ req ]
|
|
default_bits = 2048
|
|
encrypt_key = yes
|
|
distinguished_name = req_distinguished_name
|
|
|
|
[ req_distinguished_name ]
|
|
countryName = Country Name (2 letter code)
|
|
countryName_default = %CO
|
|
countryName_min = 2
|
|
countryName_max = 2
|
|
|
|
stateOrProvinceName = State or Province Name (full name)
|
|
stateOrProvinceName_default = %ST
|
|
|
|
localityName = Locality Name (eg, city)
|
|
localityName_default = %LOC
|
|
|
|
0.organizationName = Organization Name (eg, company)
|
|
0.organizationName_default = %ON
|
|
|
|
organizationalUnitName = Organizational Unit Name (eg, section)
|
|
organizationalUnitName_default = %OUN
|
|
|
|
commonName = Common Name (eg, YOUR name)
|
|
commonName_default = %CN
|
|
commonName_max = 64
|
|
|
|
emailAddress = Email Address
|
|
emailAddress_default = %EM
|
|
emailAddress_max = 64
|
|
}
|
|
|
|
global ccert
|
|
|
|
if {$ccert(FILE) == ""} {
|
|
catch {destroy .c}
|
|
mesg "No output cert file supplied"
|
|
bell
|
|
return
|
|
}
|
|
if {! [regexp {\.pem$} $ccert(FILE)]} {
|
|
append ccert(FILE) ".pem"
|
|
}
|
|
set pem $ccert(FILE)
|
|
regsub {\.pem$} $ccert(FILE) ".crt" crt
|
|
|
|
if {$ccert(ENC)} {
|
|
if {[string length $ccert(PASS)] < 4} {
|
|
catch {destroy .c}
|
|
mesg "Passphrase must be at least 4 characters long."
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
if {[string length $ccert(CO)] != 2} {
|
|
catch {destroy .c}
|
|
mesg "Country Name must be at exactly 2 characters long."
|
|
bell
|
|
return
|
|
}
|
|
if {[string length $ccert(CN)] > 64} {
|
|
catch {destroy .c}
|
|
mesg "Common Name must be less than 65 characters long."
|
|
bell
|
|
return
|
|
}
|
|
if {[string length $ccert(EM)] > 64} {
|
|
catch {destroy .c}
|
|
mesg "Email Address must be less than 65 characters long."
|
|
bell
|
|
return
|
|
}
|
|
|
|
foreach t {EM CN OUN ON LOC ST CO} {
|
|
|
|
set val $ccert($t)
|
|
if {$val == ""} {
|
|
set val "none"
|
|
}
|
|
regsub "%$t" $cfg "$val" cfg
|
|
}
|
|
|
|
global is_windows
|
|
|
|
if {$is_windows} {
|
|
# VF
|
|
set tmp "cert.cfg"
|
|
} else {
|
|
set tmp "/tmp/cert.cfg.[tpid]"
|
|
set tmp [mytmp $tmp]
|
|
catch {set fh [open $tmp "w"]}
|
|
catch {exec chmod 600 $tmp}
|
|
if {! [file exists $tmp]} {
|
|
catch {destroy .c}
|
|
mesg "cannot create: $tmp"
|
|
bell
|
|
return
|
|
}
|
|
}
|
|
set fh ""
|
|
catch {set fh [open $tmp "w"]}
|
|
if {$fh == ""} {
|
|
catch {destroy .c}
|
|
mesg "cannot create: $tmp"
|
|
bell
|
|
catch {file delete $tmp}
|
|
return
|
|
}
|
|
|
|
puts $fh $cfg
|
|
close $fh
|
|
|
|
set ossl [get_openssl]
|
|
|
|
set cmd "$ossl req -config $tmp -nodes -new -newkey rsa:2048 -x509 -batch"
|
|
if {$ccert(DAYS) != ""} {
|
|
set cmd "$cmd -days $ccert(DAYS)"
|
|
}
|
|
if {$is_windows} {
|
|
set cmd "$cmd -keyout {$pem} -out {$crt}"
|
|
} else {
|
|
set cmd "$cmd -keyout \"$pem\" -out \"$crt\""
|
|
}
|
|
|
|
if {$is_windows} {
|
|
set emess ""
|
|
if {$is_win9x} {
|
|
catch {file delete $pem}
|
|
catch {file delete $crt}
|
|
update
|
|
eval exec $cmd &
|
|
catch {raise .}
|
|
set sl 0
|
|
set max 100
|
|
#if {$ccert(ENC)} {
|
|
# set max 100
|
|
#}
|
|
set maxms [expr $max * 1000]
|
|
while {$sl < $maxms} {
|
|
set s2 [expr $sl / 1000]
|
|
mesg "running openssl ... $s2/$max"
|
|
if {[file exists $pem] && [file exists $crt]} {
|
|
after 2000
|
|
break
|
|
}
|
|
after 500
|
|
set sl [expr $sl + 500]
|
|
}
|
|
mesg ""
|
|
} else {
|
|
update
|
|
set rc [catch {eval exec $cmd} emess]
|
|
if {$rc != 0 && [regexp -nocase {error:} $emess]} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message $emess -title "OpenSSL req command failed"
|
|
return
|
|
}
|
|
}
|
|
} else {
|
|
set geometry [xterm_center_geometry]
|
|
update
|
|
unix_terminal_cmd $geometry "Running OpenSSL" "$cmd"
|
|
catch {file attributes $pem -permissions go-rw}
|
|
catch {file attributes $crt -permissions go-w}
|
|
}
|
|
catch {file delete $tmp}
|
|
|
|
set bad ""
|
|
if {! [file exists $pem]} {
|
|
set bad "$pem "
|
|
}
|
|
if {! [file exists $crt]} {
|
|
set bad "$crt"
|
|
}
|
|
if {$bad != ""} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message "Not created: $bad" -title "OpenSSL could not create cert"
|
|
catch {raise .c}
|
|
return
|
|
}
|
|
|
|
if {$ccert(ENC) && $ccert(PASS) != ""} {
|
|
set cmd "$ossl rsa -in \"$pem\" -des3 -out \"$pem\" -passout stdin"
|
|
set ph ""
|
|
set emess ""
|
|
update
|
|
set rc [catch {set ph [open "| $cmd" "w"]} emess]
|
|
if {$rc != 0 || $ph == ""} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message $emess -title "Could not encrypt private key"
|
|
catch {file delete $pem}
|
|
catch {file delete $crt}
|
|
return
|
|
}
|
|
puts $ph $ccert(PASS)
|
|
set emess ""
|
|
set rc [catch {close $ph} emess]
|
|
#puts $emess
|
|
#puts $rc
|
|
}
|
|
|
|
set in [open $crt "r"]
|
|
set out [open $pem "a"]
|
|
while {[gets $in line] > -1} {
|
|
puts $out $line
|
|
}
|
|
close $in
|
|
close $out
|
|
|
|
catch {raise .c}
|
|
set p .
|
|
if [winfo exists .c] {
|
|
set p .c
|
|
}
|
|
|
|
set reply [tk_messageBox -parent $p -type yesno -title "View Cert" -message "View Certificate and Info?"]
|
|
catch {raise .c}
|
|
if {$reply == "yes"} {
|
|
set w .view_cert
|
|
toplev $w
|
|
scroll_text $w.f
|
|
set cert ""
|
|
set fh ""
|
|
catch {set fh [open $crt "r"]}
|
|
if {$fh != ""} {
|
|
while {[gets $fh line] > -1} {
|
|
append cert "$line\n"
|
|
}
|
|
catch {close $fh}
|
|
}
|
|
|
|
global yegg
|
|
set yegg ""
|
|
button $w.b -text Dismiss -command "destroy $w; set yegg 1"
|
|
pack $w.b -side bottom -fill x
|
|
bind $w <Escape> "destroy $w; set yegg 1"
|
|
|
|
$w.f.t insert end "\n"
|
|
$w.f.t insert end "$crt:\n"
|
|
$w.f.t insert end "\n"
|
|
$w.f.t insert end $cert
|
|
$w.f.t insert end "\n"
|
|
|
|
set info [get_x509_info $crt]
|
|
$w.f.t insert end $info
|
|
|
|
pack $w.f -side top -fill both -expand 1
|
|
center_win $w
|
|
catch {raise $w}
|
|
vwait yegg
|
|
catch {raise .c}
|
|
}
|
|
|
|
set p .
|
|
if [winfo exists .c] {
|
|
set p .c
|
|
}
|
|
set reply [tk_messageBox -parent $p -type yesno -title "View Private Key" -message "View Private Key?"]
|
|
catch {raise .c}
|
|
if {$reply == "yes"} {
|
|
set w .view_key
|
|
toplev $w
|
|
scroll_text $w.f
|
|
set key ""
|
|
set fh [open $pem "r"]
|
|
while {[gets $fh line] > -1} {
|
|
append key "$line\n"
|
|
}
|
|
close $fh
|
|
|
|
global yegg
|
|
set yegg ""
|
|
button $w.b -text Dismiss -command "destroy $w; set yegg 1"
|
|
pack $w.b -side bottom -fill x
|
|
bind $w <Escape> "destroy $w; set yegg 1"
|
|
|
|
$w.f.t insert end "\n"
|
|
$w.f.t insert end "$pem:\n"
|
|
$w.f.t insert end "\n"
|
|
$w.f.t insert end $key
|
|
$w.f.t insert end "\n"
|
|
|
|
pack $w.f -side top -fill both -expand 1
|
|
center_win $w
|
|
catch {raise $w}
|
|
vwait yegg
|
|
catch {raise .c}
|
|
}
|
|
}
|
|
|
|
proc create_cert {{name ""}} {
|
|
|
|
toplev .ccrt
|
|
wm title .ccrt "Create SSL Certificate"
|
|
|
|
global uname
|
|
set h 27
|
|
if [small_height] {
|
|
set h 14
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 20
|
|
}
|
|
scroll_text .ccrt.f 80 $h
|
|
|
|
set msg {
|
|
This dialog helps you to create a simple Self-Signed SSL certificate.
|
|
|
|
On Unix the openssl(1) program must be installed and in $PATH.
|
|
On Windows, a copy of the openssl program is provided for convenience.
|
|
|
|
The resulting certificate files can be used for either:
|
|
|
|
1) authenticating yourself (VNC Viewer) to a VNC Server
|
|
or 2) your verifying the identity of a remote VNC Server.
|
|
|
|
In either case you will need to safely copy one of the generated key or
|
|
certificate files to the remote VNC Server and have the VNC Server use
|
|
it. Or you could send it to the system administrator of the VNC Server.
|
|
|
|
For the purpose of description, assume that the filename selected in the
|
|
"Save to file" entry is "vnccert.pem". That file will be generated
|
|
by this process and so will the "vnccert.crt" file. "vnccert.pem"
|
|
contains both the Private Key and the Public Certificate. "vnccert.crt"
|
|
only contains the Public Certificate.
|
|
|
|
For case 1) you would copy "vnccert.crt" to the VNC Server side and
|
|
instruct the server to use it. For x11vnc it would be for example:
|
|
|
|
x11vnc -sslverify /path/to/vnccert.crt -ssl SAVE ...
|
|
|
|
(it is also possible to handle many client certs at once in a directory,
|
|
see the -sslverify documentation). Then you would use "vnccert.pem"
|
|
as the MyCert entry in the SSL Certificates dialog.
|
|
|
|
For case 2) you would copy "vnccert.pem" to the VNC Server side and
|
|
instruct the server to use it. For x11vnc it would be for example:
|
|
|
|
x11vnc -ssl /path/to/vnccert.pem
|
|
|
|
Then you would use "vnccert.crt" as the as the ServerCert entry in the
|
|
"SSL Certificates" dialog.
|
|
|
|
|
|
Creating the Certificate:
|
|
|
|
Choose a output filename (ending in .pem) in the "Save to file" entry.
|
|
|
|
Then fill in the identification information (Country, State or Province,
|
|
etc).
|
|
|
|
The click on "Create" to generate the certificate files.
|
|
|
|
Encrypting the Private Key: It is a very good idea to encrypt the
|
|
Private Key that goes in the "vnccert.pem". The downside is that
|
|
whenever that key is used (e.g. starting up x11vnc using it) then
|
|
the passphrase will need to be created. If you do not encrypt it and
|
|
somebody steals a copy of the "vnccert.pem" file then they can pretend
|
|
to be you.
|
|
|
|
After you have created the certificate files, you must copy and import
|
|
either "vnccert.pem" or "vnccert.pem" to the remote VNC Server and
|
|
also select the other file in the "SSL Certificates" dialog.
|
|
See the description above.
|
|
|
|
For more information see:
|
|
|
|
http://www.karlrunge.com/x11vnc/ssl.html
|
|
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-int
|
|
|
|
The first one describes how to use x11vnc to create Certificate
|
|
Authority (CA) certificates in addition to Self-Signed ones.
|
|
|
|
|
|
Tip: if you choose the "Common Name" to be the internet hostname
|
|
(e.g. gateway.mydomain.com) that connections will be made to or
|
|
from that will avoid many dialogs when connecting mentioning that
|
|
the hostname does not match the Common Name.
|
|
}
|
|
.ccrt.f.t insert end $msg
|
|
|
|
global ccert ccert_init tcert
|
|
|
|
|
|
if {! [info exists ccert_init]} {
|
|
set ccert_init 1
|
|
set ccert(CO) "US"
|
|
set ccert(ST) "Massachusetts"
|
|
set ccert(LOC) "Boston"
|
|
set ccert(ON) "My Company"
|
|
set ccert(OUN) "Product Development"
|
|
set ccert(CN) "www.nowhere.none"
|
|
set ccert(EM) "admin@nowhere.none"
|
|
set ccert(DAYS) "730"
|
|
set ccert(FILE) ""
|
|
}
|
|
|
|
set ccert(ENC) 0
|
|
set ccert(PASS) ""
|
|
|
|
set tcert(CO) "Country Name (2 letter code):"
|
|
set tcert(ST) "State or Province Name (full name):"
|
|
set tcert(LOC) "Locality Name (eg, city):"
|
|
set tcert(ON) "Organization Name (eg, company):"
|
|
set tcert(OUN) "Organizational Unit Name (eg, section):"
|
|
set tcert(CN) "Common Name (eg, YOUR name):"
|
|
set tcert(EM) "Email Address:"
|
|
set tcert(DAYS) "Days until expiration:"
|
|
|
|
set idir [get_idir_certs ""]
|
|
if {$name != ""} {
|
|
if {[regexp {/} $name] || [regexp {\.pem$} $name] || [regexp {\.crt$} $name]} {
|
|
set ccert(FILE) $name
|
|
} else {
|
|
set ccert(FILE) "$idir/$name.pem"
|
|
}
|
|
} elseif {$ccert(FILE) == ""} {
|
|
set ccert(FILE) "$idir/vnccert.pem"
|
|
}
|
|
|
|
button .ccrt.cancel -text "Cancel" -command {destroy .ccrt; catch {raise .c}}
|
|
bind .ccrt <Escape> {destroy .ccrt; catch {raise .c}}
|
|
wm protocol .ccrt WM_DELETE_WINDOW {destroy .ccrt; catch {raise .c}}
|
|
|
|
button .ccrt.create -text "Generate Cert" -command {destroy .ccrt; catch {raise .c}; do_oss_create}
|
|
|
|
pack .ccrt.create .ccrt.cancel -side bottom -fill x
|
|
|
|
set ew 40
|
|
|
|
set w .ccrt.pf
|
|
frame $w
|
|
checkbutton $w.check -anchor w -variable ccert(ENC) -text \
|
|
"Encrypt Key with Passphrase" -command {check_pp}
|
|
|
|
entry $w.e -width $ew -textvariable ccert(PASS) -state disabled \
|
|
-show *
|
|
|
|
pack $w.e -side right
|
|
pack $w.check -side left -expand 1 -fill x
|
|
pack $w -side bottom -fill x
|
|
|
|
set w .ccrt.fl
|
|
frame $w
|
|
label $w.l -anchor w -text "Save to file:"
|
|
|
|
entry $w.e -width $ew -textvariable ccert(FILE)
|
|
button $w.b -text "Browse..." -command {set_createcert_file; catch {raise .ccrt}}
|
|
if {$name != ""} {
|
|
$w.b configure -state disabled
|
|
}
|
|
|
|
pack $w.e -side right
|
|
pack $w.b -side right
|
|
pack $w.l -side left -expand 1 -fill x
|
|
pack $w -side bottom -fill x
|
|
|
|
set i 0
|
|
foreach t {DAYS EM CN OUN ON LOC ST CO} {
|
|
set w .ccrt.f$i
|
|
frame $w
|
|
label $w.l -anchor w -text "$tcert($t)"
|
|
entry $w.e -width $ew -textvariable ccert($t)
|
|
pack $w.e -side right
|
|
pack $w.l -side left -expand 1 -fill x
|
|
pack $w -side bottom -fill x
|
|
incr i
|
|
}
|
|
|
|
pack .ccrt.f -side top -fill both -expand 1
|
|
|
|
center_win .ccrt
|
|
}
|
|
|
|
proc import_check_mode {w} {
|
|
global import_mode
|
|
if {$import_mode == "paste"} {
|
|
$w.mf.b configure -state disabled
|
|
$w.mf.e configure -state disabled
|
|
$w.plab configure -state normal
|
|
$w.paste.t configure -state normal
|
|
} else {
|
|
$w.mf.b configure -state normal
|
|
$w.mf.e configure -state normal
|
|
$w.plab configure -state disabled
|
|
$w.paste.t configure -state disabled
|
|
}
|
|
}
|
|
|
|
proc import_browse {par} {
|
|
global import_file
|
|
|
|
set idir ""
|
|
if {$import_file != ""} {
|
|
set idir [get_idir_certs $import_file]
|
|
}
|
|
unix_dialog_resize $par
|
|
if {$idir != ""} {
|
|
set t [tk_getOpenFile -parent $par -initialdir $idir]
|
|
} else {
|
|
set t [tk_getOpenFile -parent $par]
|
|
}
|
|
if {$t != ""} {
|
|
set import_file $t
|
|
}
|
|
catch {raise $par}
|
|
update
|
|
}
|
|
|
|
proc import_save_browse {{par ".icrt"}} {
|
|
global import_save_file
|
|
|
|
set idir ""
|
|
if {$import_save_file != ""} {
|
|
set idir [get_idir_certs $import_save_file]
|
|
}
|
|
if {$idir == ""} {
|
|
set idir [get_idir_certs ""]
|
|
}
|
|
unix_dialog_resize $par
|
|
if {$idir != ""} {
|
|
set t [tk_getSaveFile -parent $par -defaultextension ".crt" -initialdir $idir]
|
|
} else {
|
|
set t [tk_getSaveFile -parent $par -defaultextension ".crt"]
|
|
}
|
|
if {$t != ""} {
|
|
set import_save_file $t
|
|
}
|
|
catch {raise $par}
|
|
update
|
|
}
|
|
|
|
proc do_save {par} {
|
|
global import_mode import_file import_save_file
|
|
global also_save_to_accepted_certs
|
|
|
|
if {![info exists also_save_to_accepted_certs]} {
|
|
set also_save_to_accepted_certs 0
|
|
}
|
|
|
|
if {$import_save_file == "" && ! $also_save_to_accepted_certs} {
|
|
tk_messageBox -parent $par -type ok -icon error \
|
|
-message "No Save File supplied" -title "Save File"
|
|
return
|
|
}
|
|
|
|
set str ""
|
|
set subject_issuer ""
|
|
if {$import_mode == "save_cert_text"} {
|
|
global save_cert_text
|
|
set str $save_cert_text
|
|
set i 0
|
|
foreach line [split $str "\n"] {
|
|
incr i
|
|
if {$i > 50} {
|
|
break
|
|
}
|
|
if [regexp {^- subject: *(.*)$} $line m val] {
|
|
set subject_issuer "${subject_issuer}subject:$val\n"
|
|
}
|
|
if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] {
|
|
set subject_issuer "${subject_issuer}$is:$val\n"
|
|
}
|
|
if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] {
|
|
set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n"
|
|
}
|
|
}
|
|
} elseif {$import_mode == "paste"} {
|
|
set str [$par.paste.t get 1.0 end]
|
|
} else {
|
|
if {! [file exists $import_file]} {
|
|
tk_messageBox -parent $par -type ok -icon error \
|
|
-message "Input file \"$import_file\" does not exist." -title "Import File"
|
|
return
|
|
}
|
|
set fh ""
|
|
set emess ""
|
|
set rc [catch {set fh [open $import_file "r"]} emess]
|
|
if {$rc != 0 || $fh == ""} {
|
|
tk_messageBox -parent $par -type ok -icon error \
|
|
-message $emess -title "Import File: $import_file"
|
|
return
|
|
}
|
|
while {[gets $fh line] > -1} {
|
|
append str "$line\n"
|
|
}
|
|
close $fh
|
|
}
|
|
|
|
if {! [regexp {BEGIN CERTIFICATE} $str]} {
|
|
tk_messageBox -parent $par -type ok -icon error \
|
|
-message "Import Text does not contain \"BEGIN CERTIFICATE\"" -title "Imported Text"
|
|
return
|
|
}
|
|
if {! [regexp {END CERTIFICATE} $str]} {
|
|
tk_messageBox -parent $par -type ok -icon error \
|
|
-message "Import Text does not contain \"END CERTIFICATE\"" -title "Imported Text"
|
|
return
|
|
}
|
|
|
|
global is_windows
|
|
set fh ""
|
|
set emess ""
|
|
set deltmp ""
|
|
if {$import_save_file == ""} {
|
|
if {! $is_windows} {
|
|
set deltmp /tmp/import.[tpid]
|
|
} else {
|
|
set deltmp import.[tpid]
|
|
}
|
|
set deltmp [mytmp $deltmp]
|
|
set import_save_file $deltmp
|
|
}
|
|
set rc [catch {set fh [open $import_save_file "w"]} emess]
|
|
if {$rc != 0 || $fh == ""} {
|
|
tk_messageBox -parent $par -type ok -icon error \
|
|
-message $emess -title "Save File: $import_save_file"
|
|
return
|
|
}
|
|
if {! $is_windows} {
|
|
catch {file attributes $import_save_file -permissions go-w}
|
|
if {[regexp {PRIVATE} $str] || [regexp {\.pem$} $import_save_file]} {
|
|
catch {file attributes $import_save_file -permissions go-rw}
|
|
}
|
|
}
|
|
|
|
puts -nonewline $fh $str
|
|
close $fh
|
|
|
|
global do_save_saved_it
|
|
set do_save_saved_it 1
|
|
|
|
if {$also_save_to_accepted_certs} {
|
|
set ossl [get_openssl]
|
|
set fp_txt ""
|
|
set fp_txt [exec $ossl x509 -fingerprint -noout -in $import_save_file]
|
|
|
|
set adir [get_idir_certs ""]
|
|
set adir "$adir/accepted"
|
|
catch {file mkdir $adir}
|
|
|
|
set fingerprint ""
|
|
set fingerline ""
|
|
|
|
set i 0
|
|
foreach line [split $fp_txt "\n"] {
|
|
incr i
|
|
if {$i > 5} {
|
|
break
|
|
}
|
|
if [regexp -nocase {Fingerprint=(.*)} $line mv str] {
|
|
set fingerline $line
|
|
set fingerprint [string trim $str]
|
|
}
|
|
}
|
|
|
|
set fingerprint [string tolower $fingerprint]
|
|
regsub -all {:} $fingerprint "-" fingerprint
|
|
regsub -all {[\\/=]} $fingerprint "_" fingerprint
|
|
|
|
if {$subject_issuer == ""} {
|
|
set si_txt ""
|
|
set si_txt [exec $ossl x509 -subject -issuer -noout -in $import_save_file]
|
|
set sub ""
|
|
set iss ""
|
|
foreach line [split $si_txt "\n"] {
|
|
if [regexp -nocase {^subject= *(.*)$} $line mv str] {
|
|
set str [string trim $str]
|
|
set sub $str
|
|
} elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] {
|
|
set str [string trim $str]
|
|
set iss $str
|
|
}
|
|
}
|
|
if {$sub != "" && $iss != ""} {
|
|
set subject_issuer "subject:$sub\nissuer1:$iss\n"
|
|
if {$sub == $iss} {
|
|
set subject_issuer "${subject_issuer}SELF_SIGNED:1\n"
|
|
} else {
|
|
set subject_issuer "${subject_issuer}SELF_SIGNED:0\n"
|
|
}
|
|
}
|
|
}
|
|
|
|
global vncdisplay
|
|
set from [get_ssh_hp $vncdisplay]
|
|
if {$from == ""} {
|
|
set from [file tail $import_save_file]
|
|
regsub {\..*$} $from "" from
|
|
}
|
|
if {$from == ""} {
|
|
set from "import"
|
|
}
|
|
if [regexp -- {^:[0-9][0-9]*$} $from] {
|
|
set from "listen$from"
|
|
}
|
|
set hp $from
|
|
|
|
set from [string tolower $from]
|
|
regsub -all {^[+a-z]*://} $from "" from
|
|
regsub -all {:} $from "-" from
|
|
regsub -all {[\\/=]} $from "_" from
|
|
regsub -all {[ ]} $from "_" from
|
|
|
|
set crt "$adir/$from=$fingerprint.crt"
|
|
catch {file copy -force $import_save_file $crt}
|
|
|
|
global do_save_saved_hash_it
|
|
set do_save_saved_hash_it 1
|
|
save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer
|
|
}
|
|
|
|
catch {destroy $par}
|
|
set p .c
|
|
if {![winfo exists .c]} {
|
|
global accepted_cert_dialog_in_progress
|
|
if {! $accepted_cert_dialog_in_progress} {
|
|
if {$deltmp == ""} {
|
|
getcerts
|
|
update
|
|
}
|
|
}
|
|
}
|
|
if {![winfo exists .c]} {
|
|
set p .
|
|
}
|
|
catch {raise .c}
|
|
catch {destroy .scrt}
|
|
if {$deltmp != ""} {
|
|
catch {file delete $deltmp}
|
|
set import_save_file ""
|
|
return;
|
|
}
|
|
tk_messageBox -parent $p -type ok -icon info \
|
|
-message "Saved to file: $import_save_file" -title "Save File: $import_save_file"
|
|
}
|
|
|
|
proc import_cert {} {
|
|
|
|
toplev .icrt
|
|
wm title .icrt "Import SSL Certificate"
|
|
|
|
global scroll_text_focus
|
|
set scroll_text_focus 0
|
|
global uname
|
|
set h 19
|
|
if [small_height] {
|
|
set h 12
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 16
|
|
}
|
|
scroll_text .icrt.f 90 $h
|
|
set scroll_text_focus 1
|
|
|
|
set msg {
|
|
This dialog lets you import a SSL Certificate by either pasting one in or by
|
|
loading from another file. Choose which input mode you want to use by the toggle
|
|
"Paste / Read from File".
|
|
|
|
There are two types of files we use 1) Certificate only, and 2) Private Key
|
|
and Certificate.
|
|
|
|
Type 1) would be used to verify the identity of a remote VNC Server, whereas
|
|
type 2) would be used to authenticate ourselves to the remote VNC Server.
|
|
|
|
A type 1) by convention ends with file suffix ".crt" and looks like:
|
|
|
|
-----BEGIN CERTIFICATE-----
|
|
MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD
|
|
(more lines) ...
|
|
TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
|
|
-----END CERTIFICATE-----
|
|
|
|
A type 2) by convention ends with file suffix ".pem" and looks like:
|
|
|
|
-----BEGIN RSA PRIVATE KEY-----
|
|
MIIEpAIBAAKCAQEA4sApd7WaPKQRWnFe9T04D4pglQB0Ti0/dCVHxg8WEVQ8OdcW
|
|
(more lines) ...
|
|
9kBmNotUiTpvRM+e7E/zRemhvY9qraFooqMWzi9JrgYfeLfSvvFfGw==
|
|
-----END RSA PRIVATE KEY-----
|
|
-----BEGIN CERTIFICATE-----
|
|
MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD
|
|
(more lines) ...
|
|
TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
|
|
-----END CERTIFICATE-----
|
|
|
|
You do not need to use the ".crt" or ".pem" convention if you do not want to.
|
|
|
|
First, either paste in the text or set the "Read from File" filename.
|
|
|
|
Next, set the "Save to File" name to the file where the imported certificate
|
|
will be saved.
|
|
|
|
Then, click on "Save" to save the imported Certificate.
|
|
|
|
After you have imported the Certificate (or Key + Certificate), select it to
|
|
use for a connection via the "MyCert" or "ServerCert" dialog.
|
|
}
|
|
.icrt.f.t insert end $msg
|
|
|
|
global icert import_mode
|
|
|
|
set import_mode "paste"
|
|
|
|
set w .icrt.mf
|
|
frame $w
|
|
|
|
radiobutton $w.p -pady 1 -anchor w -variable import_mode -value paste \
|
|
-text "Paste" -command "import_check_mode .icrt"
|
|
|
|
radiobutton $w.f -pady 1 -anchor w -variable import_mode -value file \
|
|
-text "Read from File:" -command "import_check_mode .icrt"
|
|
|
|
global import_file
|
|
set import_file ""
|
|
entry $w.e -width 40 -textvariable import_file
|
|
|
|
button $w.b -pady 1 -anchor w -text "Browse..." -command {import_browse .icrt}
|
|
pack $w.b -side right
|
|
pack $w.p $w.f -side left
|
|
pack $w.e -side left -expand 1 -fill x
|
|
|
|
$w.b configure -state disabled
|
|
$w.e configure -state disabled
|
|
|
|
label .icrt.plab -anchor w -text "Paste Certificate here: (extra blank lines above or below are OK)"
|
|
set h 22
|
|
if [small_height] {
|
|
set h 11
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 11
|
|
}
|
|
scroll_text .icrt.paste 90 $h
|
|
|
|
button .icrt.cancel -text "Cancel" -command {destroy .icrt; catch {raise .c}}
|
|
bind .icrt <Escape> {destroy .icrt; catch {raise .c}}
|
|
wm protocol .icrt WM_DELETE_WINDOW {destroy .icrt; catch {raise .c}}
|
|
|
|
button .icrt.save -text "Save" -command {do_save .icrt}
|
|
|
|
set w .icrt.sf
|
|
frame $w
|
|
|
|
label $w.l -text "Save to File:" -anchor w
|
|
global import_save_file
|
|
set import_save_file ""
|
|
entry $w.e -width 40 -textvariable import_save_file
|
|
button $w.b -pady 1 -anchor w -text "Browse..." -command import_save_browse
|
|
|
|
global also_save_to_accepted_certs
|
|
set also_save_to_accepted_certs 0
|
|
checkbutton .icrt.ac -anchor w -variable also_save_to_accepted_certs -text \
|
|
"Also Save to the 'Accepted Certs' directory" -relief raised
|
|
|
|
pack $w.b -side right
|
|
pack $w.l -side left
|
|
pack $w.e -side left -expand 1 -fill x
|
|
|
|
pack .icrt.save .icrt.cancel .icrt.ac .icrt.sf .icrt.mf -side bottom -fill x
|
|
pack .icrt.paste .icrt.plab -side bottom -fill x
|
|
|
|
pack .icrt.f -side top -fill both -expand 1
|
|
|
|
.icrt.paste.t insert end ""
|
|
|
|
focus .icrt.paste.t
|
|
|
|
center_win .icrt
|
|
}
|
|
|
|
proc save_cert {hp} {
|
|
|
|
global cert_text
|
|
|
|
toplev .scrt
|
|
wm title .scrt "Import/Save SSL Certificate"
|
|
|
|
global scroll_text_focus
|
|
set scroll_text_focus 0
|
|
global uname
|
|
|
|
global accepted_cert_dialog_in_progress
|
|
set h 20
|
|
if {$accepted_cert_dialog_in_progress} {
|
|
set mode "accepted"
|
|
set h 15
|
|
if [small_height] {
|
|
set h 11
|
|
}
|
|
} else {
|
|
set mode "normal"
|
|
set h 20
|
|
if [small_height] {
|
|
set h 16
|
|
}
|
|
}
|
|
scroll_text .scrt.f 90 $h
|
|
|
|
set scroll_text_focus 1
|
|
|
|
set msg1 {
|
|
This dialog lets you import a SSL Certificate retrieved from a VNC server.
|
|
|
|
Be sure to have verified its authenticity via an external means (checking
|
|
the MD5 hash value sent to you by the administrator, etc)
|
|
|
|
Set "Save to File" to the filename where the imported cert will be saved.
|
|
|
|
If you also want the Certificate to be saved to the pool of certs in the
|
|
'Accepted Certs' directory, select the checkbox. By default all Servers are
|
|
verified against the certificates in this pool.
|
|
|
|
Then, click on "Save" to save the imported Certificate.
|
|
|
|
After you have imported the Certificate it will be automatically selected as
|
|
the "ServerCert" for the next connection to this host: %HOST
|
|
|
|
To make the ServerCert setting to the imported cert file PERMANENT, select
|
|
'Save' to save it in the profile for this host.
|
|
}
|
|
|
|
set msg2 {
|
|
This dialog lets you import a SSL Certificate retrieved from a VNC server.
|
|
|
|
Be sure to have verified its authenticity via an external means (checking
|
|
the MD5 hash value sent to you by the administrator, etc)
|
|
|
|
It will be added to the 'Accepted Certs' directory. The "Save to File"
|
|
below is already set to the correct directory and file name.
|
|
|
|
Click on "Save" to add it to the Accepted Certs.
|
|
|
|
It, and the other certs in that directory, will be used to authenticate
|
|
any VNC Server that has "ACCEPTED_CERTS" as the "CertsDir" value in the
|
|
"Certs..." dialog. This is the default checking policy.
|
|
}
|
|
|
|
set msg ""
|
|
if {$mode == "normal"} {
|
|
set msg $msg1
|
|
} else {
|
|
set msg $msg2
|
|
}
|
|
|
|
regsub {%HOST} $msg "$hp" msg
|
|
.scrt.f.t insert end $msg
|
|
|
|
set w .scrt.mf
|
|
frame $w
|
|
|
|
global import_file
|
|
set import_file ""
|
|
entry $w.e -width 40 -textvariable import_file
|
|
|
|
set h 22
|
|
if [small_height] {
|
|
set h 10
|
|
}
|
|
scroll_text .scrt.paste 90 $h
|
|
|
|
button .scrt.cancel -text "Cancel" -command {destroy .scrt; catch {raise .c}}
|
|
bind .scrt <Escape> {destroy .scrt; catch {raise .c}}
|
|
wm protocol .scrt WM_DELETE_WINDOW {destroy .scrt; catch {raise .c}}
|
|
|
|
global import_save_file
|
|
if {$mode == "normal"} {
|
|
button .scrt.save -text "Save" -command {do_save .scrt; set svcert $import_save_file}
|
|
} else {
|
|
button .scrt.save -text "Save" -command {do_save .scrt}
|
|
}
|
|
|
|
if [regexp -nocase -- {ACCEPT} $cert_text] {
|
|
if [regexp -nocase -- {Client certificate} $cert_text] {
|
|
if [regexp -- {^:[0-9][0-9]*$} $hp] {
|
|
if [regexp -nocase {subject=.*CN=([^/][^/]*)/} $cert_text mv0 mv1] {
|
|
regsub -all {[ ]} $mv1 "" mv1
|
|
set hp "$mv1$hp"
|
|
} else {
|
|
set hp "listen$hp"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
set w .scrt.sf
|
|
frame $w
|
|
|
|
label $w.l -text "Save to File:" -anchor w
|
|
set import_save_file "server:$hp.crt"
|
|
global is_windows
|
|
regsub -all {:} $import_save_file "-" import_save_file
|
|
|
|
set import_save_file [get_idir_certs ""]/$import_save_file
|
|
|
|
global fetch_cert_filename
|
|
if {$fetch_cert_filename != ""} {
|
|
set import_save_file $fetch_cert_filename
|
|
}
|
|
|
|
entry $w.e -width 40 -textvariable import_save_file
|
|
button $w.b -pady 1 -anchor w -text "Browse..." -command {import_save_browse .scrt}
|
|
|
|
pack $w.b -side right
|
|
pack $w.l -side left
|
|
pack $w.e -side left -expand 1 -fill x
|
|
|
|
global also_save_to_accepted_certs
|
|
set also_save_to_accepted_certs 0
|
|
if [regexp -nocase -- {ACCEPT} $cert_text] {
|
|
if [regexp -nocase -- {Client certificate} $cert_text] {
|
|
set also_save_to_accepted_certs 1
|
|
}
|
|
}
|
|
checkbutton .scrt.ac -anchor w -variable also_save_to_accepted_certs -text \
|
|
"Also Save to the 'Accepted Certs' directory" -relief raised
|
|
|
|
if {$mode == "normal"} {
|
|
pack .scrt.cancel .scrt.save .scrt.sf .scrt.ac .scrt.mf -side bottom -fill x
|
|
} else {
|
|
pack .scrt.cancel .scrt.save .scrt.sf .scrt.mf -side bottom -fill x
|
|
}
|
|
pack .scrt.paste -side bottom -fill x
|
|
|
|
pack .scrt.f -side top -fill both -expand 1
|
|
|
|
set text ""
|
|
set on 0
|
|
foreach line [split $cert_text "\n"] {
|
|
if [regexp -- {-----BEGIN CERTIFICATE-----} $line] {
|
|
incr on
|
|
}
|
|
if {$on != 1} {
|
|
continue;
|
|
}
|
|
append text "$line\n"
|
|
if [regexp -- {-----END CERTIFICATE-----} $line] {
|
|
set on 2
|
|
}
|
|
}
|
|
global save_cert_text
|
|
set save_cert_text $text
|
|
.scrt.paste.t insert end "$text"
|
|
global import_mode
|
|
set import_mode "save_cert_text"
|
|
|
|
focus .scrt.paste.t
|
|
|
|
center_win .scrt
|
|
}
|
|
|
|
|
|
proc getcerts {} {
|
|
global mycert svcert crtdir crlfil
|
|
global use_ssh use_sshssl
|
|
toplev .c
|
|
wm title .c "SSL Certificates"
|
|
frame .c.mycert
|
|
frame .c.svcert
|
|
frame .c.crtdir
|
|
frame .c.crlfil
|
|
label .c.mycert.l -anchor w -width 12 -text "MyCert:"
|
|
label .c.svcert.l -anchor w -width 12 -text "ServerCert:"
|
|
label .c.crtdir.l -anchor w -width 12 -text "CertsDir:"
|
|
label .c.crlfil.l -anchor w -width 12 -text "CRL File:"
|
|
|
|
entry .c.mycert.e -width 32 -textvariable mycert -vcmd v_mycert
|
|
entry .c.svcert.e -width 32 -textvariable svcert -vcmd v_svcert
|
|
entry .c.crtdir.e -width 32 -textvariable crtdir
|
|
entry .c.crlfil.e -width 32 -textvariable crlfil -vcmd v_crlfil
|
|
|
|
bind .c.mycert.e <Enter> {.c.mycert.e validate}
|
|
bind .c.mycert.e <Leave> {.c.mycert.e validate}
|
|
bind .c.svcert.e <Enter> {.c.svcert.e validate}
|
|
bind .c.svcert.e <Leave> {.c.svcert.e validate}
|
|
|
|
button .c.mycert.b -text "Browse..." -command {set_mycert .c; catch {raise .c}}
|
|
button .c.svcert.b -text "Browse..." -command {set_svcert .c; catch {raise .c}}
|
|
button .c.crtdir.b -text "Browse..." -command {set_crtdir .c; catch {raise .c}}
|
|
button .c.crlfil.b -text "Browse..." -command {set_crlfil .c; catch {raise .c}}
|
|
|
|
button .c.mycert.i -text "Info" -command {show_mycert}
|
|
button .c.svcert.i -text "Info" -command {show_svcert}
|
|
button .c.crtdir.i -text "Info" -command {}
|
|
button .c.crlfil.i -text "Info" -command {show_crlfil}
|
|
|
|
bind .c.mycert.b <Enter> "v_mycert"
|
|
bind .c.svcert.b <Enter> "v_svcert"
|
|
bind .c.crlfil.b <Enter> "v_crlfil"
|
|
|
|
.c.mycert.i configure -state disabled
|
|
.c.svcert.i configure -state disabled
|
|
.c.crtdir.i configure -state disabled
|
|
.c.crlfil.i configure -state disabled
|
|
|
|
bind .c.mycert.b <B3-ButtonRelease> "show_mycert"
|
|
bind .c.svcert.b <B3-ButtonRelease> "show_svcert"
|
|
bind .c.crlfil.b <B3-ButtonRelease> "show_crlfil"
|
|
|
|
set do_crl 1
|
|
set do_row 1
|
|
|
|
set c .c
|
|
if {$do_row} {
|
|
frame .c.b0
|
|
set c .c.b0
|
|
}
|
|
|
|
button $c.create -text "Create Certificate ..." -command {create_cert}
|
|
button $c.import -text "Import Certificate ..." -command {import_cert}
|
|
button $c.delete -text "Delete Certificate ..." -command {delete_cert .c}
|
|
|
|
if {$c != ".c"} {
|
|
pack $c.create $c.import $c.delete -fill x -expand 1 -side left
|
|
}
|
|
|
|
frame .c.b
|
|
button .c.b.done -text "Done" -command {catch {destroy .c}}
|
|
bind .c <Escape> {destroy .c}
|
|
button .c.b.help -text "Help" -command help_certs
|
|
pack .c.b.help .c.b.done -fill x -expand 1 -side left
|
|
|
|
set wlist [list mycert svcert crtdir]
|
|
lappend wlist crlfil
|
|
|
|
foreach w $wlist {
|
|
pack .c.$w.l -side left
|
|
pack .c.$w.e -side left -expand 1 -fill x
|
|
pack .c.$w.b -side left
|
|
pack .c.$w.i -side left
|
|
bind .c.$w.e <Return> ".c.$w.b invoke"
|
|
if {$use_ssh} {
|
|
.c.$w.l configure -state disabled
|
|
.c.$w.e configure -state disabled
|
|
.c.$w.b configure -state disabled
|
|
}
|
|
}
|
|
|
|
global svcert_default_force mycert_default_force crlfil_default_force
|
|
if {$mycert_default_force} {
|
|
.c.mycert.e configure -state readonly
|
|
.c.mycert.b configure -state disabled
|
|
}
|
|
if {$svcert_default_force} {
|
|
.c.svcert.e configure -state readonly
|
|
.c.svcert.b configure -state disabled
|
|
.c.crtdir.e configure -state readonly
|
|
.c.crtdir.b configure -state disabled
|
|
}
|
|
if {$crlfil_default_force} {
|
|
.c.crlfil.e configure -state readonly
|
|
.c.crlfil.b configure -state disabled
|
|
}
|
|
|
|
if {$mycert != ""} {
|
|
v_mycert
|
|
}
|
|
if {$svcert != ""} {
|
|
v_svcert
|
|
}
|
|
if {$crlfil != ""} {
|
|
v_crlfil
|
|
}
|
|
|
|
set wlist [list .c.mycert .c.svcert .c.crtdir]
|
|
if {$do_crl} {
|
|
lappend wlist .c.crlfil
|
|
}
|
|
if {$c != ".c"} {
|
|
lappend wlist $c
|
|
} else {
|
|
lappend wlist .c.create .c.import .c.delete
|
|
}
|
|
lappend wlist .c.b
|
|
|
|
eval pack $wlist -side top -fill x
|
|
|
|
center_win .c
|
|
wm resizable .c 1 0
|
|
|
|
focus .c
|
|
}
|
|
|
|
proc get_profiles_dir {} {
|
|
global env is_windows
|
|
|
|
set dir ""
|
|
if {$is_windows} {
|
|
if [info exists env(SSVNC_HOME)] {
|
|
set t "$env(SSVNC_HOME)/ss_vnc"
|
|
regsub -all {\\} $t "/" t
|
|
regsub -all {//*} $t "/" t
|
|
if {! [file isdirectory $t]} {
|
|
catch {file mkdir $t}
|
|
}
|
|
if [file isdirectory $t] {
|
|
set dir $t
|
|
set s "$t/profiles"
|
|
if {! [file exists $s]} {
|
|
catch {file mkdir $s}
|
|
}
|
|
}
|
|
}
|
|
if {$dir == ""} {
|
|
set t [file dirname [pwd]]
|
|
set t "$t/profiles"
|
|
if [file isdirectory $t] {
|
|
set dir $t
|
|
}
|
|
}
|
|
} elseif [info exists env(SSVNC_HOME)] {
|
|
set t "$env(SSVNC_HOME)/.vnc"
|
|
catch {file mkdir $t}
|
|
if [file isdirectory $t] {
|
|
set dir $t
|
|
set s "$t/profiles"
|
|
if {! [file exists $s]} {
|
|
catch {file mkdir $s}
|
|
}
|
|
}
|
|
}
|
|
|
|
if {$dir != ""} {
|
|
|
|
} elseif [info exists env(SSVNC_BASEDIR)] {
|
|
set dir $env(SSVNC_BASEDIR)
|
|
} else {
|
|
set dir [pwd]
|
|
}
|
|
if [file isdirectory "$dir/profiles"] {
|
|
set dir "$dir/profiles"
|
|
}
|
|
return $dir
|
|
}
|
|
|
|
proc globalize {} {
|
|
global defs
|
|
foreach var [array names defs] {
|
|
uplevel global $var
|
|
}
|
|
}
|
|
|
|
proc load_include {include dir} {
|
|
global include_vars defs
|
|
|
|
if [info exists include_vars] {
|
|
unset include_vars
|
|
}
|
|
|
|
foreach inc [split $include ", "] {
|
|
set f [string trim $inc]
|
|
#puts "f=$f";
|
|
if {$f == ""} {
|
|
continue
|
|
}
|
|
set try ""
|
|
if {[regexp {/} $f] || [regexp {\\} $f]} {
|
|
set try $f;
|
|
} else {
|
|
set try "$dir/$f"
|
|
}
|
|
if {! [file exists $try]} {
|
|
set try "$dir/$f.vnc"
|
|
}
|
|
#puts "try: $try"
|
|
if [file exists $try] {
|
|
set fh ""
|
|
catch {set fh [open $try "r"]}
|
|
if {$fh == ""} {
|
|
continue
|
|
}
|
|
mesg "Applying template: $inc"
|
|
after 100
|
|
while {[gets $fh line] > -1} {
|
|
append inc_str "$line\n"
|
|
if [regexp {^([^=]*)=(.*)$} $line m var val] {
|
|
if {! [info exists defs($var)]} {
|
|
continue
|
|
}
|
|
if {$var == "include_list"} {
|
|
continue
|
|
}
|
|
set pct 0
|
|
if {$var == "smb_mount_list"} {
|
|
set pct 1
|
|
}
|
|
if {$var == "port_knocking_list"} {
|
|
set pct 1
|
|
}
|
|
if {$pct} {
|
|
regsub -all {%%%} $val "\n" val
|
|
}
|
|
if {$val != $defs($var)} {
|
|
#puts "include_vars $var $val"
|
|
set include_vars($var) $val
|
|
}
|
|
}
|
|
}
|
|
catch {close $fh}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc unix_dialog_resize {{w .}} {
|
|
global env is_windows uname unix_dialog_size
|
|
set ok 0
|
|
set width 600
|
|
set height 300
|
|
if {[info exists env(SSVNC_BIGGER_DIALOG)]} {
|
|
set ok 1
|
|
if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $env(SSVNC_BIGGER_DIALOG) m wi he]} {
|
|
set width $wi;
|
|
set height $he;
|
|
}
|
|
} elseif {[info exists env(USER)] && $env(USER) == "runge"} {
|
|
set ok 1
|
|
}
|
|
if {$ok} {
|
|
# this is a personal hack because tk_getOpenFile size is not configurable.
|
|
if {!$is_windows && $uname != "Darwin"} {
|
|
if {$w == "."} {
|
|
set w2 .__tk_filedialog
|
|
} else {
|
|
set w2 $w.__tk_filedialog
|
|
}
|
|
set w3 $w2.icons.canvas
|
|
global udr_w4
|
|
set udr_w4 $w2.f2.cancel
|
|
if {! [info exists unix_dialog_size($w)]} {
|
|
after 50 {global udr_w4; catch {$udr_w4 invoke}}
|
|
tk_getOpenFile -parent $w -initialdir /
|
|
set unix_dialog_size($w) 1
|
|
}
|
|
if [winfo exists $w3] {
|
|
catch {$w3 configure -width $width}
|
|
catch {$w3 configure -height $height}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc delete_profile {{parent "."}} {
|
|
|
|
globalize
|
|
|
|
set dir [get_profiles_dir]
|
|
|
|
unix_dialog_resize $parent
|
|
set file [tk_getOpenFile -parent $parent -initialdir $dir -title "DELETE VNC Profile"]
|
|
|
|
if {$file == ""} {
|
|
return
|
|
}
|
|
|
|
set tail [file tail $file]
|
|
|
|
set ans [tk_messageBox -type okcancel -title "Delete $tail" -message "Really Delete $file?" -icon warning]
|
|
|
|
if {$ans == "ok"} {
|
|
catch {file delete $file}
|
|
mesg "Deleted $tail"
|
|
} else {
|
|
mesg "Delete Skipped."
|
|
}
|
|
}
|
|
|
|
proc load_profile {{parent "."} {infile ""}} {
|
|
global profdone
|
|
global vncdisplay
|
|
|
|
globalize
|
|
|
|
set dir [get_profiles_dir]
|
|
|
|
if {$infile != ""} {
|
|
set file $infile
|
|
} else {
|
|
unix_dialog_resize
|
|
set file [tk_getOpenFile -parent $parent -defaultextension \
|
|
".vnc" -initialdir $dir -title "Load VNC Profile"]
|
|
}
|
|
|
|
if {$file == ""} {
|
|
set profdone 1
|
|
return
|
|
}
|
|
set fh [open $file "r"]
|
|
if {! [info exists fh]} {
|
|
set profdone 1
|
|
return
|
|
}
|
|
|
|
set goto_mode "";
|
|
set str ""
|
|
set include ""
|
|
set sw 1
|
|
while {[gets $fh line] > -1} {
|
|
append str "$line\n"
|
|
if [regexp {^include_list=(.*)$} $line m val] {
|
|
set include $val
|
|
}
|
|
global ssh_only ts_only
|
|
if {$ssh_only || $ts_only} {
|
|
if [regexp {use_ssh=0} $line] {
|
|
if {$sw} {
|
|
mesg "Switching to SSVNC mode."
|
|
set goto_mode "ssvnc"
|
|
update
|
|
after 300
|
|
} else {
|
|
bell
|
|
mesg "Cannot Load an SSL profile in SSH-ONLY mode."
|
|
set profdone 1
|
|
close $fh
|
|
return
|
|
}
|
|
}
|
|
}
|
|
if {! $ts_only} {
|
|
if [regexp {ts_mode=1} $line] {
|
|
if {$sw} {
|
|
mesg "Switching to Terminal Services mode."
|
|
set goto_mode "tsonly"
|
|
update
|
|
after 300
|
|
} else {
|
|
bell
|
|
mesg "Cannot Load a Terminal Svcs profile SSVNC mode."
|
|
set profdone 1
|
|
close $fh
|
|
return
|
|
}
|
|
}
|
|
} else {
|
|
if [regexp {ts_mode=0} $line] {
|
|
if {$sw} {
|
|
mesg "Switching to SSVNC mode."
|
|
set goto_mode "ssvnc"
|
|
update
|
|
after 300
|
|
} else {
|
|
bell
|
|
mesg "Cannot Load a Terminal Svcs profile SSVNC mode."
|
|
set profdone 1
|
|
close $fh
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
close $fh
|
|
|
|
if {$include != ""} {
|
|
load_include $include $dir
|
|
}
|
|
|
|
if {$goto_mode == "tsonly"} {
|
|
to_tsonly
|
|
} elseif {$goto_mode == "ssvnc"} {
|
|
to_ssvnc
|
|
} elseif {$goto_mode == "sshvnc"} {
|
|
to_sshvnc
|
|
}
|
|
set_defaults
|
|
|
|
global include_vars
|
|
if [info exists include_vars] {
|
|
foreach var [array names include_vars] {
|
|
set $var $include_vars($var)
|
|
}
|
|
}
|
|
|
|
|
|
global use_ssl use_ssh use_sshssl
|
|
set use_ssl 0
|
|
set use_ssh 0
|
|
set use_sshssl 0
|
|
|
|
global defs
|
|
foreach line [split $str "\n"] {
|
|
set line [string trim $line]
|
|
if [regexp {^#} $line] {
|
|
continue
|
|
}
|
|
if [regexp {^([^=]*)=(.*)$} $line m var val] {
|
|
if {$var == "disp"} {
|
|
set vncdisplay $val
|
|
continue
|
|
}
|
|
if [info exists defs($var)] {
|
|
set pct 0
|
|
if {$var == "smb_mount_list"} {
|
|
set pct 1
|
|
}
|
|
if {$var == "port_knocking_list"} {
|
|
set pct 1
|
|
}
|
|
if {$pct} {
|
|
regsub -all {%%%} $val "\n" val
|
|
}
|
|
set $var $val
|
|
}
|
|
}
|
|
}
|
|
|
|
init_vncdisplay
|
|
if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
|
|
if {! $disable_all_encryption} {
|
|
set use_ssl 1
|
|
}
|
|
}
|
|
if {$use_ssl} {
|
|
set use_ssh 0
|
|
set use_sshssl 0
|
|
} elseif {$use_ssh && $use_sshssl} {
|
|
set use_ssh 0
|
|
}
|
|
sync_use_ssl_ssh
|
|
|
|
set compresslevel_text "Compress Level: $use_compresslevel"
|
|
set quality_text "Quality: $use_quality"
|
|
|
|
set profdone 1
|
|
putty_pw_entry check
|
|
listen_adjust
|
|
unixpw_adjust
|
|
|
|
global last_load
|
|
set last_load [file tail $file]
|
|
|
|
global uname darwin_cotvnc
|
|
if {$uname == "Darwin"} {
|
|
if {$use_x11_macosx} {
|
|
set darwin_cotvnc 0;
|
|
} else {
|
|
set darwin_cotvnc 1;
|
|
}
|
|
}
|
|
|
|
mesg "Loaded [file tail $file]"
|
|
}
|
|
|
|
proc sync_use_ssl_ssh {} {
|
|
global use_ssl use_ssh use_sshssl
|
|
global disable_all_encryption
|
|
if {$use_ssl} {
|
|
ssl_ssh_adjust ssl
|
|
} elseif {$use_ssh} {
|
|
ssl_ssh_adjust ssh
|
|
} elseif {$use_sshssl} {
|
|
ssl_ssh_adjust sshssl
|
|
} elseif {$disable_all_encryption} {
|
|
ssl_ssh_adjust none
|
|
} else {
|
|
ssl_ssh_adjust ssl
|
|
}
|
|
}
|
|
|
|
proc save_profile {{parent "."}} {
|
|
global is_windows uname
|
|
global profdone
|
|
global include_vars defs
|
|
global ts_only
|
|
global last_load
|
|
|
|
globalize
|
|
|
|
set dir [get_profiles_dir]
|
|
|
|
set vncdisp [get_vncdisplay]
|
|
|
|
set dispf [string trim $vncdisp]
|
|
if {$dispf != ""} {
|
|
regsub {[ ].*$} $dispf "" dispf
|
|
regsub -all {/} $dispf "" dispf
|
|
} else {
|
|
global ts_only
|
|
if {$ts_only} {
|
|
mesg "No VNC Terminal Server supplied."
|
|
} else {
|
|
mesg "No VNC Host:Disp supplied."
|
|
}
|
|
bell
|
|
return
|
|
}
|
|
if {$is_windows || $uname == "Darwin"} {
|
|
regsub -all {:} $dispf "-" dispf
|
|
} else {
|
|
regsub -all {:} $dispf "-" dispf
|
|
}
|
|
regsub -all {[\[\]]} $dispf "" dispf
|
|
if {$ts_only && ![regexp {^TS-} $dispf]} {
|
|
set dispf "TS-$dispf"
|
|
}
|
|
if {![regexp {\.vnc$} $dispf]} {
|
|
set dispf "$dispf.vnc"
|
|
}
|
|
|
|
set guess $dispf
|
|
if {$last_load != ""} {
|
|
set guess $last_load
|
|
}
|
|
|
|
unix_dialog_resize
|
|
set file [tk_getSaveFile -parent $parent -defaultextension ".vnc" \
|
|
-initialdir $dir -initialfile "$guess" -title "Save VNC Profile"]
|
|
if {$file == ""} {
|
|
set profdone 1
|
|
return
|
|
}
|
|
set fh [open $file "w"]
|
|
if {! [info exists fh]} {
|
|
set profdone 1
|
|
return
|
|
}
|
|
set h [string trim $vncdisp]
|
|
set p $h
|
|
# XXX host_part
|
|
regsub {:[0-9][0-9]*$} $h "" h
|
|
set host $h
|
|
regsub {[ ].*$} $p "" p
|
|
regsub {^.*:} $p "" p
|
|
regsub { .*$} $p "" p
|
|
if {$p == ""} {
|
|
set p 0
|
|
} elseif {![regexp {^[-0-9][0-9]*$} $p]} {
|
|
set p 0
|
|
}
|
|
if {$p < 0} {
|
|
set port $p
|
|
} elseif {$p < 200} {
|
|
set port [expr $p + 5900]
|
|
} else {
|
|
set port $p
|
|
}
|
|
|
|
set h [string trim $vncdisp]
|
|
regsub {cmd=.*$} $h "" h
|
|
set h [string trim $h]
|
|
if {! [regexp {[ ]} $h]} {
|
|
set h ""
|
|
} else {
|
|
regsub {^.*[ ]} $h "" h
|
|
}
|
|
if {$h == ""} {
|
|
set proxy ""
|
|
set proxyport ""
|
|
} else {
|
|
set p $h
|
|
regsub {:[0-9][0-9]*$} $h "" h
|
|
set proxy $h
|
|
regsub {[ ].*$} $p "" p
|
|
regsub {^.*:} $p "" p
|
|
if {$p == ""} {
|
|
set proxyport 0
|
|
} else {
|
|
set proxyport $p
|
|
}
|
|
}
|
|
|
|
puts $fh "\[connection\]"
|
|
puts $fh "host=$host"
|
|
puts $fh "port=$port"
|
|
puts $fh "proxyhost=$proxy"
|
|
puts $fh "proxyport=$proxyport"
|
|
puts $fh "disp=$vncdisp"
|
|
puts $fh "\n\[options\]"
|
|
puts $fh "# parameters commented out with '#' indicate the default setting."
|
|
|
|
if {$include_list != ""} {
|
|
load_include $include_list [get_profiles_dir]
|
|
}
|
|
global sshssl_sw
|
|
if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
|
|
if {$sshssl_sw == "none"} {
|
|
set disable_all_encryption 1
|
|
}
|
|
}
|
|
|
|
global ts_only ssh_only
|
|
if {$ts_only} {
|
|
set ts_mode 1
|
|
} else {
|
|
set ts_mode 0
|
|
}
|
|
foreach var [lsort [array names defs]] {
|
|
eval set val \$$var
|
|
set pre ""
|
|
if {$val == $defs($var)} {
|
|
set pre "#"
|
|
}
|
|
if {$ssh_only && $var == "use_ssh"} {
|
|
set pre ""
|
|
}
|
|
set pct 0
|
|
if {$var == "smb_mount_list"} {
|
|
set pct 1
|
|
}
|
|
if {$var == "port_knocking_list"} {
|
|
set pct 1
|
|
}
|
|
if {$include_list != "" && [info exists include_vars($var)]} {
|
|
if {$val == $include_vars($var)} {
|
|
if {$pct} {
|
|
regsub -all "\n" $val "%%%" val
|
|
}
|
|
puts $fh "#from include: $var=$val"
|
|
continue
|
|
}
|
|
}
|
|
if {$pct} {
|
|
regsub -all "\n" $val "%%%" val
|
|
}
|
|
puts $fh "$pre$var=$val"
|
|
}
|
|
|
|
close $fh
|
|
|
|
mesg "Saved Profile: [file tail $file]"
|
|
|
|
set last_load [file tail $file]
|
|
|
|
set profdone 1
|
|
}
|
|
|
|
proc set_ssh {} {
|
|
global use_ssl
|
|
if {$use_ssl} {
|
|
ssl_ssh_adjust ssh
|
|
}
|
|
}
|
|
|
|
proc expand_IP {redir} {
|
|
if {! [regexp {:IP:} $redir]} {
|
|
return $redir
|
|
}
|
|
if {! [regexp {(-R).*:IP:} $redir]} {
|
|
return $redir
|
|
}
|
|
|
|
set ip [guess_ip]
|
|
set ip [string trim $ip]
|
|
if {$ip == ""} {
|
|
return $redir
|
|
}
|
|
|
|
regsub -all {:IP:} $redir ":$ip:" redir
|
|
return $redir
|
|
}
|
|
|
|
proc rand_port {} {
|
|
global rand_port_list
|
|
|
|
set p ""
|
|
for {set i 0} {$i < 30} {incr i} {
|
|
set p [expr 25000 + 35000 * rand()]
|
|
set p [expr round($p)]
|
|
if {![info exists rand_port_list($p)]} {
|
|
break
|
|
}
|
|
}
|
|
if {$p == ""} {
|
|
unset rand_port_list
|
|
set p [expr 25000 + 35000 * rand()]
|
|
set p [expr round($p)]
|
|
}
|
|
set rand_port_list($p) 1
|
|
return $p
|
|
}
|
|
|
|
proc get_cups_redir {} {
|
|
global cups_local_server cups_remote_port
|
|
global cups_local_smb_server cups_remote_smb_port
|
|
|
|
regsub -all {[ ]} $cups_local_server "" cups_local_server
|
|
regsub -all {[ ]} $cups_remote_port "" cups_remote_port
|
|
regsub -all {[ ]} $cups_local_smb_server "" cups_local_smb_server
|
|
regsub -all {[ ]} $cups_remote_smb_port "" cups_remote_smb_port
|
|
|
|
set redir ""
|
|
|
|
if {$cups_local_server != "" && $cups_remote_port != ""} {
|
|
set redir "$cups_remote_port:$cups_local_server"
|
|
regsub -all {['" ]} $redir {} redir; #"
|
|
set redir " -R $redir"
|
|
}
|
|
if {$cups_local_smb_server != "" && $cups_remote_smb_port != ""} {
|
|
set redir2 "$cups_remote_smb_port:$cups_local_smb_server"
|
|
regsub -all {['" ]} $redir2 {} redir2; #"
|
|
set redir "$redir -R $redir2"
|
|
}
|
|
set redir [expand_IP $redir]
|
|
return $redir
|
|
}
|
|
|
|
proc get_additional_redir {} {
|
|
global additional_port_redirs additional_port_redirs_list
|
|
global ts_only choose_x11vnc_opts
|
|
if {! $additional_port_redirs || $additional_port_redirs_list == ""} {
|
|
return ""
|
|
}
|
|
if {$ts_only && !$choose_x11vnc_opts} {
|
|
return ""
|
|
}
|
|
set redir [string trim $additional_port_redirs_list]
|
|
regsub -all {['"]} $redir {} redir; #"
|
|
set redir " $redir"
|
|
set redir [expand_IP $redir]
|
|
return $redir
|
|
}
|
|
|
|
proc get_sound_redir {} {
|
|
global sound_daemon_remote_port sound_daemon_local_port
|
|
global sound_daemon_x11vnc
|
|
|
|
regsub -all {[ ]} $sound_daemon_remote_port "" sound_daemon_remote_port
|
|
regsub -all {[ ]} $sound_daemon_local_port "" sound_daemon_local_port
|
|
|
|
set redir ""
|
|
if {$sound_daemon_local_port == "" || $sound_daemon_remote_port == ""} {
|
|
return $redir
|
|
}
|
|
|
|
set loc $sound_daemon_local_port
|
|
if {! [regexp {:} $loc]} {
|
|
global uname
|
|
if {$uname == "Darwin"} {
|
|
set loc "127.0.0.1:$loc"
|
|
} else {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
global win_localhost
|
|
set loc "$win_localhost:$loc"
|
|
} else {
|
|
set loc "localhost:$loc"
|
|
}
|
|
}
|
|
}
|
|
set redir "$sound_daemon_remote_port:$loc"
|
|
regsub -all {['" ]} $redir {} redir; #"
|
|
set redir " -R $redir"
|
|
set redir [expand_IP $redir]
|
|
return $redir
|
|
}
|
|
|
|
proc get_smb_redir {} {
|
|
global smb_mount_list
|
|
|
|
set s [string trim $smb_mount_list]
|
|
if {$s == ""} {
|
|
return ""
|
|
}
|
|
|
|
set did(0) 1
|
|
set redir ""
|
|
set mntlist ""
|
|
|
|
foreach line [split $s "\r\n"] {
|
|
set str [string trim $line]
|
|
if {$str == ""} {
|
|
continue
|
|
}
|
|
if {[regexp {^#} $str]} {
|
|
continue
|
|
}
|
|
|
|
set port ""
|
|
if [regexp {^([0-9][0-9]*)[ \t][ \t]*(.*)} $str mvar port rest] {
|
|
# leading port
|
|
set str [string trim $rest]
|
|
}
|
|
|
|
# grab: //share /dest [host[:port]]
|
|
set share ""
|
|
set dest ""
|
|
set hostport ""
|
|
foreach item [split $str] {
|
|
if {$item == ""} {
|
|
continue
|
|
}
|
|
if {$share == ""} {
|
|
set share [string trim $item]
|
|
} elseif {$dest == ""} {
|
|
set dest [string trim $item]
|
|
} elseif {$hostport == ""} {
|
|
set hostport [string trim $item]
|
|
}
|
|
}
|
|
|
|
regsub {^~/} $dest {$HOME/} dest
|
|
|
|
# work out the local host:port
|
|
set lhost ""
|
|
set lport ""
|
|
if {$hostport != ""} {
|
|
if [regexp {(.*):([0-9][0-9]*)} $hostport mvar lhost lport] {
|
|
;
|
|
} else {
|
|
set lhost $hostport
|
|
set lport 139
|
|
}
|
|
} else {
|
|
if [regexp {//([^/][^/]*)/} $share mvar h] {
|
|
if [regexp {(.*):([0-9][0-9]*)} $h mvar lhost lport] {
|
|
;
|
|
} else {
|
|
set lhost $h
|
|
set lport 139
|
|
}
|
|
} else {
|
|
global is_windows win_localhost
|
|
set lhost "localhost"
|
|
if {$is_windows} {
|
|
set lhost $win_localhost
|
|
}
|
|
set lport 139
|
|
}
|
|
}
|
|
|
|
if {$port == ""} {
|
|
if [info exists did("$lhost:$lport")] {
|
|
# reuse previous one:
|
|
set port $did("$lhost:$lport")
|
|
} else {
|
|
# choose one at random:
|
|
for {set i 0} {$i < 3} {incr i} {
|
|
set port [expr 20100 + 9000 * rand()]
|
|
set port [expr round($port)]
|
|
if { ! [info exists did($port)] } {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
set did($port) 1
|
|
}
|
|
|
|
if {$mntlist != ""} {
|
|
append mntlist " "
|
|
}
|
|
append mntlist "$share,$dest,$port"
|
|
|
|
if { ! [info exists did("$lhost:$lport")] } {
|
|
append redir " -R $port:$lhost:$lport"
|
|
set did("$lhost:$lport") $port
|
|
}
|
|
}
|
|
|
|
regsub -all {['"]} $redir {} redir; #"
|
|
set redir [expand_IP $redir]
|
|
|
|
regsub -all {['"]} $mntlist {} mntlist; #"
|
|
|
|
set l [list]
|
|
lappend l $redir
|
|
lappend l $mntlist
|
|
return $l
|
|
}
|
|
|
|
proc ugly_setup_scripts {mode tag} {
|
|
|
|
set cmd(1) {
|
|
SSHD_PID=""
|
|
FLAG=$HOME/.vnc-helper-flag__PID__
|
|
|
|
if [ "X$USER" = "X" ]; then
|
|
USER=$LOGNAME
|
|
fi
|
|
|
|
DO_CUPS=0
|
|
cups_dir=$HOME/.cups
|
|
cups_cfg=$cups_dir/client.conf
|
|
cups_host=localhost
|
|
cups_port=NNNN
|
|
|
|
DO_SMB=0
|
|
DO_SMB_SU=0
|
|
DO_SMB_WAIT=0
|
|
smb_mounts=
|
|
DONE_PORT_CHECK=NNNN
|
|
smb_script=$HOME/.smb-mounts__PID__.sh
|
|
|
|
DO_SOUND=0
|
|
DO_SOUND_KILL=0
|
|
DO_SOUND_RESTART=0
|
|
sound_daemon_remote_prog=
|
|
sound_daemon_remote_args=
|
|
|
|
findpid() {
|
|
db=0
|
|
back=30
|
|
touch $FLAG
|
|
tty=`tty | sed -e "s,/dev/,,"`
|
|
|
|
if [ "X$TOPPID" = "X" ]; then
|
|
TOPPID=$$
|
|
if [ $db = 1 ]; then echo "set TOPPID to $TOPPID"; fi
|
|
back=70
|
|
fi
|
|
#back=5
|
|
if [ $db = 1 ]; then echo "TOPPID=$TOPPID THISPID=$$ back=$back"; fi
|
|
|
|
i=1
|
|
while [ $i -lt $back ]
|
|
do
|
|
try=`expr $TOPPID - $i`
|
|
if [ $try -lt 1 ]; then
|
|
try=`expr 32768 + $try`
|
|
fi
|
|
if [ $db = 1 ]; then echo try-1=$try; ps $try; fi
|
|
if ps $try 2>/dev/null | grep "sshd.*$USER" | grep "$tty" >/dev/null; then
|
|
if [ $db = 1 ]; then echo Found=$try; fi
|
|
SSHD_PID="$try"
|
|
echo
|
|
ps $try
|
|
echo
|
|
break
|
|
fi
|
|
i=`expr $i + 1`
|
|
done
|
|
|
|
if [ "X$SSHD_PID" = "X" ]; then
|
|
back=`expr $back + 20`
|
|
#back=5
|
|
|
|
for fallback in 2 3
|
|
do
|
|
i=1
|
|
while [ $i -lt $back ]
|
|
do
|
|
try=`expr $TOPPID - $i`
|
|
if [ $try -lt 1 ]; then
|
|
try=`expr 32768 + $try`
|
|
fi
|
|
match="sshd.*$USER"
|
|
if [ $fallback = 3 ]; then
|
|
match="sshd"
|
|
fi
|
|
if [ $db = 1 ]; then echo "try-$fallback=$try match=$match"; ps $try; fi
|
|
if ps $try 2>/dev/null | grep "$match" >/dev/null; then
|
|
if [ $db = 1 ]; then echo Found=$try; fi
|
|
SSHD_PID="$try"
|
|
echo
|
|
ps $try
|
|
echo
|
|
break
|
|
fi
|
|
i=`expr $i + 1`
|
|
done
|
|
if [ "X$SSHD_PID" != "X" ]; then
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
#curlie}
|
|
};
|
|
|
|
set cmd(2) {
|
|
#curlie{
|
|
if [ "X$SSHD_PID" = "X" ]; then
|
|
if [ $db = 1 ]; then
|
|
echo
|
|
pstr=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf"`
|
|
echo "$pstr"
|
|
fi
|
|
plist=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf" | awk "{print \\\$4}" | sort -n`
|
|
if [ $db = 1 ]; then
|
|
echo
|
|
echo "$plist"
|
|
fi
|
|
for try in $plist
|
|
do
|
|
if [ $db = 1 ]; then echo try-final=$try; ps $try; fi
|
|
if echo "$try" | grep "^[0-9][0-9]*\\\$" > /dev/null; then
|
|
:
|
|
else
|
|
continue
|
|
fi
|
|
if ps $try | egrep vnc-helper > /dev/null; then
|
|
:
|
|
else
|
|
if [ $db = 1 ]; then echo Found=$try; fi
|
|
SSHD_PID=$try
|
|
echo
|
|
ps $try
|
|
echo
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
if [ "X$SSHD_PID" = "X" ]; then
|
|
#ugh
|
|
SSHD_PID=$$
|
|
fi
|
|
|
|
echo "vnc-helper: [for cups/smb/esd] SSHD_PID=$SSHD_PID MY_PID=$$ TTY=$tty"
|
|
echo "vnc-helper: To force me to finish: rm $FLAG"
|
|
}
|
|
|
|
wait_til_ssh_gone() {
|
|
try_perl=""
|
|
if type perl >/dev/null 2>&1; then
|
|
if [ -d /proc -a -e /proc/$$ ]; then
|
|
try_perl="1"
|
|
fi
|
|
fi
|
|
if [ "X$try_perl" = "X1" ]; then
|
|
# try to avoid wasting pids:
|
|
perl -e "while (1) {if(-d \"/proc\" && ! -e \"/proc/$SSHD_PID\"){exit} if(! -f \"$FLAG\"){exit} sleep 1;}"
|
|
else
|
|
while [ 1 ]
|
|
do
|
|
ps $SSHD_PID > /dev/null 2>&1
|
|
if [ $? != 0 ]; then
|
|
break
|
|
fi
|
|
if [ ! -f $FLAG ]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
fi
|
|
rm -f $FLAG
|
|
if [ "X$DO_SMB_WAIT" = "X1" ]; then
|
|
rm -f $smb_script
|
|
fi
|
|
}
|
|
};
|
|
|
|
set cmd(3) {
|
|
update_client_conf() {
|
|
mkdir -p $cups_dir
|
|
|
|
if [ ! -f $cups_cfg.back ]; then
|
|
touch $cups_cfg.back
|
|
fi
|
|
if [ ! -f $cups_cfg ]; then
|
|
touch $cups_cfg
|
|
fi
|
|
|
|
if grep ssvnc-auto $cups_cfg > /dev/null; then
|
|
:
|
|
else
|
|
cp -p $cups_cfg $cups_cfg.back
|
|
fi
|
|
|
|
echo "#-ssvnc-auto:" > $cups_cfg
|
|
sed -e "s/^ServerName/#-ssvnc-auto-#ServerName/" $cups_cfg.back >> $cups_cfg
|
|
echo "ServerName $cups_host:$cups_port" >> $cups_cfg
|
|
|
|
echo
|
|
echo "-----------------------------------------------------------------"
|
|
echo "On `hostname`:"
|
|
echo
|
|
echo "The CUPS $cups_cfg config file has been set to:"
|
|
echo
|
|
cat $cups_cfg | grep -v "^#-ssvnc-auto:" | sed -e "s/^/ /"
|
|
echo
|
|
echo "If there are problems automatically restoring it, edit or remove"
|
|
echo "the file to go back to the local CUPS settings."
|
|
echo
|
|
echo "A backup has been placed in: $cups_cfg.back"
|
|
echo
|
|
echo "See the SSVNC CUPS dialog for more details on printing."
|
|
if type lpstat >/dev/null 2>&1; then
|
|
echo
|
|
echo "lpstat -a output:"
|
|
echo
|
|
(lpstat -a 2>&1 | sed -e "s/^/ /") &
|
|
sleep 0.5 >/dev/null 2>&1
|
|
fi
|
|
echo "-----------------------------------------------------------------"
|
|
echo
|
|
}
|
|
|
|
reset_client_conf() {
|
|
cp $cups_cfg $cups_cfg.tmp
|
|
grep -v "^ServerName" $cups_cfg.tmp | grep -v "^#-ssvnc-auto:" | sed -e "s/^#-ssvnc-auto-#ServerName/ServerName/" > $cups_cfg
|
|
rm -f $cups_cfg.tmp
|
|
}
|
|
|
|
cupswait() {
|
|
trap "" INT QUIT HUP
|
|
trap "reset_client_conf; rm -f $FLAG; exit" TERM
|
|
wait_til_ssh_gone
|
|
reset_client_conf
|
|
}
|
|
};
|
|
|
|
# if [ "X$DONE_PORT_CHECK" != "X" ]; then
|
|
# if type perl >/dev/null 2>&1; then
|
|
# 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 &
|
|
# if [ $? = 0 ]; then
|
|
# have_perl_done="1"
|
|
# fi
|
|
# fi
|
|
# fi
|
|
|
|
set cmd(4) {
|
|
smbwait() {
|
|
trap "" INT QUIT HUP
|
|
wait_til_ssh_gone
|
|
}
|
|
do_smb_mounts() {
|
|
if [ "X$smb_mounts" = "X" ]; then
|
|
return
|
|
fi
|
|
echo > $smb_script
|
|
have_perl_done=""
|
|
echo "echo" >> $smb_script
|
|
dests=""
|
|
for mnt in $smb_mounts
|
|
do
|
|
smfs=`echo "$mnt" | awk -F, "{print \\\$1}"`
|
|
dest=`echo "$mnt" | awk -F, "{print \\\$2}"`
|
|
port=`echo "$mnt" | awk -F, "{print \\\$3}"`
|
|
dest=`echo "$dest" | sed -e "s,__USER__,$USER,g" -e "s,__HOME__,$HOME,g"`
|
|
if [ ! -d $dest ]; then
|
|
mkdir -p $dest
|
|
fi
|
|
echo "echo SMBMOUNT:" >> $smb_script
|
|
echo "echo smbmount $smfs $dest -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script
|
|
echo "smbmount \"$smfs\" \"$dest\" -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script
|
|
echo "echo; df \"$dest\"; echo" >> $smb_script
|
|
dests="$dests $dest"
|
|
done
|
|
#curlie}
|
|
};
|
|
|
|
set cmd(5) {
|
|
echo "(" >> $smb_script
|
|
echo "un_mnt() {" >> $smb_script
|
|
for dest in $dests
|
|
do
|
|
echo " echo smbumount $dest" >> $smb_script
|
|
echo " smbumount \"$dest\"" >> $smb_script
|
|
done
|
|
echo "}" >> $smb_script
|
|
echo "trap \"\" INT QUIT HUP" >> $smb_script
|
|
echo "trap \"un_mnt; exit\" TERM" >> $smb_script
|
|
|
|
try_perl=""
|
|
if type perl >/dev/null 2>&1; then
|
|
try_perl=1
|
|
fi
|
|
uname=`uname`
|
|
if [ "X$uname" != "XLinux" -a "X$uname" != "XSunOS" -a "X$uname" != "XDarwin" ]; then
|
|
try_perl=""
|
|
fi
|
|
|
|
if [ "X$try_perl" = "X" ]; then
|
|
echo "while [ -f $smb_script ]" >> $smb_script
|
|
echo "do" >> $smb_script
|
|
echo " sleep 1" >> $smb_script
|
|
echo "done" >> $smb_script
|
|
else
|
|
echo "perl -e \"while (-f \\\"$smb_script\\\") {sleep 1;} exit 0;\"" >> $smb_script
|
|
fi
|
|
echo "un_mnt" >> $smb_script
|
|
echo ") &" >> $smb_script
|
|
echo "-----------------------------------------------------------------"
|
|
echo "On `hostname`:"
|
|
echo
|
|
if [ "$DO_SMB_SU" = "0" ]; then
|
|
echo "We now run the smbmount script as user $USER"
|
|
echo
|
|
echo sh $smb_script
|
|
sh $smb_script
|
|
rc=0
|
|
elif [ "$DO_SMB_SU" = "1" ]; then
|
|
echo "We now run the smbmount script via su(1)"
|
|
echo
|
|
echo "The first \"Password:\" will be for that of root to run the smbmount script."
|
|
echo
|
|
echo "Subsequent \"Password:\" will be for the SMB share(s) (hit Return if no passwd)"
|
|
echo
|
|
echo SU:
|
|
echo "su root -c \"sh $smb_script\""
|
|
su root -c "sh $smb_script"
|
|
rc=$?
|
|
elif [ "$DO_SMB_SU" = "2" ]; then
|
|
echo "We now run the smbmount script via sudo(8)"
|
|
echo
|
|
echo "The first \"Password:\" will be for that of the sudo(8) password."
|
|
echo
|
|
echo "Subsequent \"Password:\" will be for the SMB shares (hit enter if no passwd)"
|
|
echo
|
|
echo SUDO:
|
|
sd="sudo"
|
|
echo "$sd sh $smb_script"
|
|
$sd sh $smb_script
|
|
rc=$?
|
|
fi
|
|
};
|
|
|
|
set cmd(6) {
|
|
#curlie{
|
|
echo
|
|
if [ "$rc" = 0 ]; then
|
|
if [ "X$have_perl_done" = "X1" -o 1 = 1 ] ; then
|
|
echo
|
|
echo "Your SMB shares will be unmounted when the VNC connection closes,"
|
|
echo "*AS LONG AS* No Applications have any of the share files opened or are"
|
|
echo "cd-ed into any of the share directories."
|
|
echo
|
|
echo "Try to make sure nothing is accessing the SMB shares before disconnecting"
|
|
echo "the VNC session. If you fail to do that follow these instructions:"
|
|
fi
|
|
echo
|
|
echo "To unmount your SMB shares make sure no applications are still using any of"
|
|
echo "the files and no shells are still cd-ed into the share area, then type:"
|
|
echo
|
|
echo " rm -f $smb_script"
|
|
echo
|
|
echo "In the worst case run: smbumount /path/to/mount/point for each mount as root"
|
|
echo
|
|
echo "Even with the remote redirection gone the kernel should umount after a timeout."
|
|
else
|
|
echo
|
|
if [ "$DO_SMB_SU" = "1" ]; then
|
|
echo "su(1) to run smbmount(8) failed."
|
|
elif [ "$DO_SMB_SU" = "2" ]; then
|
|
echo "sudo(8) to run smbmount(8) failed."
|
|
fi
|
|
rm -f $smb_script
|
|
fi
|
|
echo "-----------------------------------------------------------------"
|
|
echo
|
|
}
|
|
};
|
|
|
|
set cmd(7) {
|
|
|
|
setup_sound() {
|
|
dpid=""
|
|
d=$sound_daemon_remote_prog
|
|
if type pgrep >/dev/null 2>/dev/null; then
|
|
dpid=`pgrep -U $USER -x $d | head -1`
|
|
else
|
|
dpid=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -v grep | head -1`
|
|
fi
|
|
echo "-----------------------------------------------------------------"
|
|
echo "On `hostname`:"
|
|
echo
|
|
echo "Setting up Sound: pid=$dpid"
|
|
if [ "X$dpid" != "X" ]; then
|
|
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/"`
|
|
if [ "X$DO_SOUND_KILL" = "X1" ]; then
|
|
echo "Stopping sound daemon: $sound_daemon_remote_prog $dpid"
|
|
echo "sound cmd: $dcmd"
|
|
kill -TERM $dpid
|
|
fi
|
|
fi
|
|
echo "-----------------------------------------------------------------"
|
|
echo
|
|
}
|
|
|
|
reset_sound() {
|
|
if [ "X$DO_SOUND_RESTART" = "X1" ]; then
|
|
d=$sound_daemon_remote_prog
|
|
a=$sound_daemon_remote_args
|
|
echo "Restaring sound daemon: $d $a"
|
|
$d $a </dev/null >/dev/null 2>&1 &
|
|
fi
|
|
}
|
|
|
|
soundwait() {
|
|
trap "" INT QUIT HUP
|
|
trap "reset_sound; rm -f $FLAG; exit" TERM
|
|
wait_til_ssh_gone
|
|
reset_sound
|
|
}
|
|
|
|
|
|
findpid
|
|
|
|
if [ $DO_SMB = 1 ]; then
|
|
do_smb_mounts
|
|
fi
|
|
|
|
waiter=0
|
|
|
|
if [ $DO_CUPS = 1 ]; then
|
|
update_client_conf
|
|
cupswait </dev/null >/dev/null 2>/dev/null &
|
|
waiter=1
|
|
fi
|
|
|
|
if [ $DO_SOUND = 1 ]; then
|
|
setup_sound
|
|
soundwait </dev/null >/dev/null 2>/dev/null &
|
|
waiter=1
|
|
fi
|
|
if [ $DO_SMB_WAIT = 1 ]; then
|
|
if [ $waiter != 1 ]; then
|
|
smbwait </dev/null >/dev/null 2>/dev/null &
|
|
waiter=1
|
|
fi
|
|
fi
|
|
|
|
|
|
#FINMSG
|
|
echo "--main-vnc-helper-finished--"
|
|
#cat $0
|
|
rm -f $0
|
|
exit 0
|
|
};
|
|
|
|
set cmdall ""
|
|
|
|
for {set i 1} {$i <= 7} {incr i} {
|
|
set v $cmd($i);
|
|
regsub -all "\n" $v "%" v
|
|
regsub -all {.curlie.} $v "" v
|
|
set cmd($i) $v
|
|
append cmdall "echo "
|
|
if {$i == 1} {
|
|
append cmdall {TOPPID=$$ %}
|
|
}
|
|
append cmdall {'}
|
|
append cmdall $cmd($i)
|
|
append cmdall {' | tr '%' '\n'}
|
|
if {$i == 1} {
|
|
append cmdall {>}
|
|
} else {
|
|
append cmdall {>>}
|
|
}
|
|
append cmdall {$HOME/.vnc-helper-cmd__PID__; }
|
|
}
|
|
append cmdall {sh $HOME/.vnc-helper-cmd__PID__; }
|
|
|
|
regsub -all {vnc-helper-cmd} $cmdall "vnc-helper-cmd-$mode" cmdall
|
|
if {$tag == ""} {
|
|
set tag [pid]
|
|
}
|
|
regsub -all {__PID__} $cmdall "$tag" cmdall
|
|
|
|
set orig $cmdall
|
|
|
|
global use_cups cups_local_server cups_remote_port cups_manage_rcfile ts_only ts_cups_manage_rcfile cups_x11vnc
|
|
regsub -all {[ ]} $cups_local_server "" cups_local_server
|
|
regsub -all {[ ]} $cups_remote_port "" cups_remote_port
|
|
if {$use_cups} {
|
|
set dorc 0
|
|
if {$ts_only} {
|
|
if {$ts_cups_manage_rcfile} {
|
|
set dorc 1
|
|
}
|
|
} else {
|
|
if {$cups_manage_rcfile} {
|
|
set dorc 1
|
|
}
|
|
}
|
|
if {$dorc && $mode == "post"} {
|
|
if {$cups_local_server != "" && $cups_remote_port != ""} {
|
|
regsub {DO_CUPS=0} $cmdall {DO_CUPS=1} cmdall
|
|
regsub {cups_port=NNNN} $cmdall "cups_port=$cups_remote_port" cmdall
|
|
}
|
|
}
|
|
}
|
|
|
|
global use_smbmnt smb_su_mode smb_mounts
|
|
if {$use_smbmnt} {
|
|
if {$smb_mounts != ""} {
|
|
set smbm $smb_mounts
|
|
regsub -all {%USER} $smbm "__USER__" smbm
|
|
regsub -all {%HOME} $smbm "__HOME__" smbm
|
|
if {$mode == "pre"} {
|
|
regsub {DO_SMB=0} $cmdall {DO_SMB=1} cmdall
|
|
if {$smb_su_mode == "su"} {
|
|
regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall
|
|
} elseif {$smb_su_mode == "sudo"} {
|
|
regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=2} cmdall
|
|
} elseif {$smb_su_mode == "none"} {
|
|
regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=0} cmdall
|
|
} else {
|
|
regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall
|
|
}
|
|
regsub {smb_mounts=} $cmdall "smb_mounts=\"$smbm\"" cmdall
|
|
} elseif {$mode == "post"} {
|
|
regsub {DO_SMB_WAIT=0} $cmdall {DO_SMB_WAIT=1} cmdall
|
|
}
|
|
}
|
|
}
|
|
|
|
global use_sound
|
|
if {$use_sound} {
|
|
if {$mode == "pre"} {
|
|
global sound_daemon_remote_cmd sound_daemon_kill sound_daemon_restart
|
|
if {$sound_daemon_kill} {
|
|
regsub {DO_SOUND_KILL=0} $cmdall {DO_SOUND_KILL=1} cmdall
|
|
regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall
|
|
}
|
|
if {$sound_daemon_restart} {
|
|
regsub {DO_SOUND_RESTART=0} $cmdall {DO_SOUND_RESTART=1} cmdall
|
|
regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall
|
|
}
|
|
set sp [string trim $sound_daemon_remote_cmd]
|
|
regsub {[ \t].*$} $sp "" sp
|
|
set sa [string trim $sound_daemon_remote_cmd]
|
|
regsub {^[^ \t][^ \t]*[ \t][ \t]*} $sa "" sa
|
|
regsub {sound_daemon_remote_prog=} $cmdall "sound_daemon_remote_prog=\"$sp\"" cmdall
|
|
regsub {sound_daemon_remote_args=} $cmdall "sound_daemon_remote_args=\"$sa\"" cmdall
|
|
}
|
|
}
|
|
|
|
if {$mode == "pre"} {
|
|
set dopre 0
|
|
if {$use_smbmnt && $smb_mounts != ""} {
|
|
set dopre 1
|
|
}
|
|
if {$use_sound && $sound_daemon_kill} {
|
|
set dopre 1
|
|
}
|
|
if {$dopre} {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
regsub {#FINMSG} $cmdall {echo "Now Go Click on the Label to Start the 2nd SSH"} cmdall
|
|
} else {
|
|
regsub {#FINMSG} $cmdall {echo "Finished with the 1st SSH tasks, the 2nd SSH should start shortly..."} cmdall
|
|
}
|
|
}
|
|
}
|
|
|
|
set cmdstr $cmdall
|
|
|
|
if {"$orig" == "$cmdall"} {
|
|
set cmdstr ""
|
|
}
|
|
global env
|
|
if [info exists env(SSVNC_DEBUG_CUPS)] {
|
|
regsub -all {db=0} $cmdstr "db=1" cmdstr
|
|
set pout ""
|
|
regsub -all {%} $cmdstr "\n" pout
|
|
puts stderr "\nSERVICE REDIR COMMAND:\n\n$pout\n"
|
|
}
|
|
return $cmdstr
|
|
}
|
|
|
|
proc ts_unixpw_dialog {} {
|
|
|
|
toplev .uxpw
|
|
wm title .uxpw "Use unixpw"
|
|
|
|
scroll_text .uxpw.f 80 14
|
|
|
|
global ts_unixpw
|
|
|
|
set msg {
|
|
This enables the x11vnc unixpw mode. A Login: and Password: dialog
|
|
will be presented in the VNC Viewer for the user to provide any Unix
|
|
username and password whose session he wants to connect to. So this
|
|
may require typing in the password a 2nd time after the one for SSH.
|
|
|
|
This mode is useful if a shared terminal services user (e.g. 'tsuser')
|
|
is used for the SSH login part (say via the SSH authorized_keys
|
|
mechanism and all users share the same private SSH key for 'tsuser').
|
|
|
|
Note, However that the default usage of a per-user SSH login should
|
|
be the simplest and also sufficient for most situations, in which
|
|
case this "Use unixpw" option should NOT be selected.
|
|
}
|
|
.uxpw.f.t insert end $msg
|
|
|
|
button .uxpw.cancel -text "Cancel" -command {destroy .uxpw; set ts_unixpw 0}
|
|
bind .uxpw <Escape> {destroy .uxpw; set ts_unixpw 0}
|
|
wm protocol .uxpw WM_DELETE_WINDOW {destroy .uxpw; set ts_unixpw 0}
|
|
|
|
button .uxpw.done -text "Done" -command {destroy .uxpw; set ts_unixpw 1}
|
|
|
|
pack .uxpw.done .uxpw.cancel -side bottom -fill x
|
|
pack .uxpw.f -side top -fill both -expand 1
|
|
|
|
center_win .uxpw
|
|
}
|
|
|
|
proc ts_vncshared_dialog {} {
|
|
|
|
toplev .vncs
|
|
wm title .vncs "VNC Shared"
|
|
|
|
scroll_text .vncs.f 80 23
|
|
|
|
global ts_vncshared
|
|
|
|
set msg {
|
|
Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous
|
|
shared access of the remote desktop: You simply log in as many
|
|
times from as many different locations with 'tsvnc' as you like.
|
|
|
|
However, doing it that way starts up a new x11vnc for each connection.
|
|
In some circumstances you may want a single x11vnc running but allow
|
|
multiple VNC viewers to access it simultaneously.
|
|
|
|
This option (VNC Shared) enables that rarer usage case by passing
|
|
'-shared' to the remote x11vnc command.
|
|
|
|
With this option enabled, the new shared connections must
|
|
still connect to the Terminal Server via SSH for encryption and
|
|
authentication. They must also do the normal SSH port redirection
|
|
to access the x11vnc port (usually 5900, but look for the PORT=
|
|
output for the actual value).
|
|
|
|
They could use SSVNC for that, or do it manually in terminal
|
|
windows, more information:
|
|
|
|
http://www.karlrunge.com/x11vnc/#tunnelling
|
|
}
|
|
.vncs.f.t insert end $msg
|
|
|
|
button .vncs.cancel -text "Cancel" -command {destroy .vncs; set ts_vncshared 0}
|
|
bind .vncs <Escape> {destroy .vncs; set ts_vncshared 0}
|
|
wm protocol .vncs WM_DELETE_WINDOW {destroy .vncs; set ts_vncshared 0}
|
|
button .vncs.done -text "Done" -command {destroy .vncs; set ts_vncshared 1}
|
|
|
|
pack .vncs.done .vncs.cancel -side bottom -fill x
|
|
pack .vncs.f -side top -fill both -expand 1
|
|
|
|
center_win .vncs
|
|
}
|
|
|
|
proc ts_multi_dialog {} {
|
|
|
|
toplev .mult
|
|
wm title .mult "Multiple Sessions"
|
|
|
|
scroll_text .mult.f 80 21
|
|
|
|
global ts_multisession choose_multisession
|
|
|
|
set msg {
|
|
Normally in Terminal Services mode (tsvnc) your user account (the
|
|
one you SSH in as) can only have a single Terminal Services X session
|
|
running at a time on one server machine.
|
|
|
|
This is simply because x11vnc chooses the first Desktop (X session)
|
|
of yours that it can find. It will never create a 2nd X session
|
|
because it keeps finding the 1st one.
|
|
|
|
To have Multiple Sessions for one username on a single machine,
|
|
choose a unique Session "Tag", that will be associated with the X
|
|
session and x11vnc will only choose the one that has this Tag.
|
|
|
|
For this to work ALL of your sessions on the server machine must
|
|
have a different tag (that is, if you have an existing session with
|
|
no tag, x11vnc might find a tagged one first instead of it).
|
|
|
|
The tag must be made of only letters, numbers, dash, or underscore.
|
|
|
|
Examples: KDE_SMALL, gnome-2, test1
|
|
}
|
|
.mult.f.t insert end $msg
|
|
|
|
frame .mult.c
|
|
label .mult.c.l -anchor w -text "Tag:"
|
|
entry .mult.c.e -width 20 -textvariable ts_multisession
|
|
pack .mult.c.l -side left
|
|
pack .mult.c.e -side left -expand 1 -fill x
|
|
|
|
button .mult.cancel -text "Cancel" -command {destroy .mult; set choose_multisession 0}
|
|
bind .mult <Escape> {destroy .mult; set choose_multisession 0}
|
|
wm protocol .mult WM_DELETE_WINDOW {destroy .mult; set choose_multisession 0}
|
|
|
|
bind .mult.c.e <Return> {destroy .mult; set choose_multisession 1}
|
|
button .mult.done -text "Done" -command {destroy .mult; set choose_multisession 1}
|
|
|
|
pack .mult.done .mult.cancel .mult.c -side bottom -fill x
|
|
pack .mult.f -side top -fill both -expand 1
|
|
|
|
center_win .mult
|
|
focus .mult.c.e
|
|
}
|
|
|
|
proc ts_xlogin_dialog {} {
|
|
|
|
toplev .xlog
|
|
wm title .xlog "X Login Greeter"
|
|
|
|
set h 33
|
|
if [small_height] {
|
|
set h 28
|
|
}
|
|
scroll_text .xlog.f 80 $h
|
|
|
|
global ts_xlogin
|
|
|
|
set msg {
|
|
If you have root (sudo(1)) permission on the remote machine, you
|
|
can have x11vnc try to connect to a X display(s) that has No One
|
|
Logged In Yet. This is most likely the login greeter running on
|
|
the Physical console. sudo(1) is used to run x11vnc with FD_XDM=1.
|
|
|
|
This is different from tsvnc's regular Terminal Services mode where
|
|
usually a virtual (RAM only, e.g. Xvfb) X server used. With this option
|
|
it is the physical graphics hardware that will be connected to.
|
|
|
|
Note that if your user is ALREADY logged into the physical display,
|
|
you don't need to use this X Login option because x11vnc should find
|
|
it in its normal find-display procedure and not need sudo(1).
|
|
|
|
An initial ssh running 'sudo id' is performed to try to 'prime'
|
|
sudo so the 2nd one that runs x11vnc does not need a password.
|
|
This may not always succeed...
|
|
|
|
Note that if someone is already logged into the display console
|
|
via XDM (GDM, KDM etc.) you will see and control their X session.
|
|
|
|
Otherwise, you will get the Greeter X login screen where you can
|
|
log in via username and password. Your SSVNC 'Terminal Services'
|
|
Desktop Type, Size, Printing etc. settings will be ignored in this
|
|
case of course because XDM, GDM, or KDM is creating your X session,
|
|
not x11vnc.
|
|
|
|
Note that the GDM display manager has a setting KillInitClients in
|
|
gdm.conf that will kill x11vnc right after you log in, and so you would
|
|
have to repeat the whole process ('Connect' button) to attach to your
|
|
session. See http://www.karlrunge.com/x11vnc/faq.html#faq-display-manager
|
|
for more info.
|
|
}
|
|
.xlog.f.t insert end $msg
|
|
|
|
button .xlog.cancel -text "Cancel" -command {destroy .xlog; set ts_xlogin 0}
|
|
bind .xlog <Escape> {destroy .xlog; set ts_xlogin 0}
|
|
wm protocol .xlog WM_DELETE_WINDOW {destroy .xlog; set ts_xlogin 0}
|
|
|
|
button .xlog.done -text "Done" -command {destroy .xlog; set ts_xlogin 1}
|
|
|
|
pack .xlog.done .xlog.cancel -side bottom -fill x
|
|
pack .xlog.f -side top -fill both -expand 1
|
|
|
|
center_win .xlog
|
|
}
|
|
|
|
|
|
proc ts_othervnc_dialog {} {
|
|
|
|
toplev .ovnc
|
|
wm title .ovnc "Other VNC Server"
|
|
|
|
scroll_text .ovnc.f 80 21
|
|
|
|
global ts_othervnc choose_othervnc
|
|
|
|
set msg {
|
|
The x11vnc program running on the remote machine can be instructed to
|
|
immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so)
|
|
VNC server.
|
|
|
|
It should be a little faster to have x11vnc forward the VNC protocol
|
|
rather than having it poll the corresponding X server for changes
|
|
in the way it normally does and translate to VNC.
|
|
|
|
This mode also enables a simple way to add SSL or find X display
|
|
support to a 3rd party VNC Server lacking these features.
|
|
|
|
In the entry box put the other vnc display, e.g. "localhost:0" or
|
|
"somehost:5".
|
|
|
|
The string "find" in the entry will have x11vnc try to find an X
|
|
display in its normal way, and then redirect to the corresponding VNC
|
|
server port. This assumes if the X display is, say, :2 (i.e. port
|
|
6002) then the VNC display is also :2 (i.e. port 5902). This mode is
|
|
the same as an "X Server Type" of "Xvnc.redirect" (and overrides it).
|
|
}
|
|
.ovnc.f.t insert end $msg
|
|
|
|
frame .ovnc.c
|
|
label .ovnc.c.l -anchor w -text "Other VNC Server:"
|
|
entry .ovnc.c.e -width 20 -textvariable ts_othervnc
|
|
pack .ovnc.c.l -side left
|
|
pack .ovnc.c.e -side left -expand 1 -fill x
|
|
|
|
button .ovnc.cancel -text "Cancel" -command {destroy .ovnc; set choose_othervnc 0}
|
|
bind .ovnc <Escape> {destroy .ovnc; set choose_othervnc 0}
|
|
wm protocol .ovnc WM_DELETE_WINDOW {destroy .ovnc; set choose_othervnc 0}
|
|
button .ovnc.done -text "Done" -command {destroy .ovnc; set choose_othervnc 1}
|
|
bind .ovnc.c.e <Return> {destroy .ovnc; set choose_othervnc 1}
|
|
|
|
if {$ts_othervnc == ""} {
|
|
set ts_othervnc "find"
|
|
}
|
|
|
|
pack .ovnc.done .ovnc.cancel .ovnc.c -side bottom -fill x
|
|
pack .ovnc.f -side top -fill both -expand 1
|
|
|
|
center_win .ovnc
|
|
focus .ovnc.c.e
|
|
}
|
|
|
|
proc ts_sleep_dialog {} {
|
|
|
|
toplev .eslp
|
|
wm title .eslp "Extra Sleep"
|
|
|
|
scroll_text .eslp.f 80 5
|
|
|
|
global extra_sleep
|
|
|
|
set msg {
|
|
Sleep: Enter a number to indicate how many extra seconds to sleep
|
|
while waiting for the VNC viewer to start up. On Windows this
|
|
can give extra time to enter the Putty/Plink password, etc.
|
|
}
|
|
.eslp.f.t insert end $msg
|
|
|
|
frame .eslp.c
|
|
label .eslp.c.l -anchor w -text "Extra Sleep:"
|
|
entry .eslp.c.e -width 20 -textvariable extra_sleep
|
|
pack .eslp.c.l -side left
|
|
pack .eslp.c.e -side left -expand 1 -fill x
|
|
|
|
button .eslp.cancel -text "Cancel" -command {destroy .eslp; set choose_sleep 0}
|
|
bind .eslp <Escape> {destroy .eslp; set choose_sleep 0}
|
|
wm protocol .eslp WM_DELETE_WINDOW {destroy .eslp; set choose_sleep 0}
|
|
button .eslp.done -text "Done" -command {destroy .eslp; set choose_sleep 1}
|
|
bind .eslp.c.e <Return> {destroy .eslp; set choose_sleep 1}
|
|
|
|
global choose_sleep
|
|
if {! $choose_sleep} {
|
|
set extra_sleep ""
|
|
}
|
|
|
|
pack .eslp.done .eslp.cancel .eslp.c -side bottom -fill x
|
|
pack .eslp.f -side top -fill both -expand 1
|
|
|
|
center_win .eslp
|
|
focus .eslp.c.e
|
|
}
|
|
|
|
proc ts_putty_args_dialog {} {
|
|
|
|
toplev .parg
|
|
wm title .parg "Putty Args"
|
|
|
|
scroll_text .parg.f 80 5
|
|
|
|
global putty_args
|
|
|
|
set msg {
|
|
Putty Args: Enter a string to be added to every plink.exe and putty.exe
|
|
command line. For example: -i C:\mykey.ppk
|
|
}
|
|
.parg.f.t insert end $msg
|
|
|
|
frame .parg.c
|
|
label .parg.c.l -anchor w -text "Putty Args:"
|
|
entry .parg.c.e -width 20 -textvariable putty_args
|
|
pack .parg.c.l -side left
|
|
pack .parg.c.e -side left -expand 1 -fill x
|
|
|
|
button .parg.cancel -text "Cancel" -command {destroy .parg; set choose_parg 0}
|
|
bind .parg <Escape> {destroy .parg; set choose_parg 0}
|
|
wm protocol .parg WM_DELETE_WINDOW {destroy .parg; set choose_parg 0}
|
|
button .parg.done -text "Done" -command {destroy .parg; set choose_parg 1}
|
|
bind .parg.c.e <Return> {destroy .parg; set choose_parg 1}
|
|
|
|
global choose_parg
|
|
if {! $choose_parg} {
|
|
set putty_args ""
|
|
}
|
|
|
|
pack .parg.done .parg.cancel .parg.c -side bottom -fill x
|
|
pack .parg.f -side top -fill both -expand 1
|
|
|
|
center_win .parg
|
|
focus .parg.c.e
|
|
}
|
|
|
|
proc ts_ncache_dialog {} {
|
|
|
|
toplev .nche
|
|
wm title .nche "Client-Side Caching"
|
|
|
|
scroll_text .nche.f 80 22
|
|
|
|
global ts_ncache choose_ncache
|
|
|
|
set msg {
|
|
This enables the *experimental* x11vnc client-side caching mode.
|
|
It often gives nice speedups, but can sometimes lead to painting
|
|
errors or window "flashing". (you can repaint the screen by tapping
|
|
the Left Alt key 3 times in a row)
|
|
|
|
It is a very simple but hoggy method: uncompressed image pixmaps are
|
|
stored in the viewer in a large (20-100MB) display region beneath
|
|
the actual display screen. You may need also to adjust your VNC Viewer
|
|
to not show this region (the SSVNC Unix viewer does it automatically).
|
|
|
|
The scheme uses a lot of RAM, but at least it has the advantage that
|
|
it works with every VNC Viewer. Otherwise the VNC protocol would
|
|
need to be modified, changing both the server and the viewer.
|
|
|
|
Set the x11vnc "-ncache" parameter to an even integer between 2
|
|
and 20. This is the increase in area factor over the normal screen
|
|
for the caching region. So 10 means use 10 times the RAM to store
|
|
pixmaps. The default is 8.
|
|
|
|
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
|
|
}
|
|
.nche.f.t insert end $msg
|
|
|
|
frame .nche.c
|
|
label .nche.c.l -anchor w -text "ncache:"
|
|
radiobutton .nche.c.r2 -text "2" -variable ts_ncache -value "2"
|
|
radiobutton .nche.c.r4 -text "4" -variable ts_ncache -value "4"
|
|
radiobutton .nche.c.r6 -text "6" -variable ts_ncache -value "6"
|
|
radiobutton .nche.c.r8 -text "8" -variable ts_ncache -value "8"
|
|
radiobutton .nche.c.r10 -text "10" -variable ts_ncache -value "10"
|
|
radiobutton .nche.c.r12 -text "12" -variable ts_ncache -value "12"
|
|
radiobutton .nche.c.r14 -text "14" -variable ts_ncache -value "14"
|
|
radiobutton .nche.c.r16 -text "16" -variable ts_ncache -value "16"
|
|
radiobutton .nche.c.r18 -text "18" -variable ts_ncache -value "18"
|
|
radiobutton .nche.c.r20 -text "20" -variable ts_ncache -value "20"
|
|
pack .nche.c.l -side left
|
|
pack .nche.c.r2 .nche.c.r4 .nche.c.r6 .nche.c.r8 .nche.c.r10 \
|
|
.nche.c.r12 .nche.c.r14 .nche.c.r16 .nche.c.r18 .nche.c.r20 -side left
|
|
button .nche.cancel -text "Cancel" -command {destroy .nche; set choose_ncache 0}
|
|
bind .nche <Escape> {destroy .nche; set choose_ncache 0}
|
|
wm protocol .nche WM_DELETE_WINDOW {destroy .nche; set choose_ncache 0}
|
|
button .nche.done -text "Done" -command {destroy .nche; set choose_ncache 1}
|
|
|
|
pack .nche.done .nche.cancel .nche.c -side bottom -fill x
|
|
pack .nche.f -side top -fill both -expand 1
|
|
|
|
center_win .nche
|
|
}
|
|
|
|
proc ts_x11vnc_opts_dialog {} {
|
|
|
|
toplev .x11v
|
|
wm title .x11v "x11vnc Options"
|
|
|
|
set h 23
|
|
if [small_height] {
|
|
set h 21
|
|
}
|
|
scroll_text .x11v.f 80 $h
|
|
|
|
global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts
|
|
global additional_port_redirs_list
|
|
|
|
set msg {
|
|
If you are an expert with x11vnc's endless options and tweaking
|
|
parameters feel free to specify any you want here in "Options".
|
|
|
|
Also, if you need to specify the path to the x11vnc program on the
|
|
remote side because it will not be in $PATH, put it in the "Full
|
|
Path" entry.
|
|
|
|
Port Redirs are additional SSH "-L port:host:port" or "-R port:host:port"
|
|
(forward or reverse, resp.) port redirections you want. In SSVNC mode,
|
|
see the detailed description under: Options -> Advanced -> Port Redirs.
|
|
|
|
Some potentially useful options:
|
|
|
|
-solid -scale -scale_cursor
|
|
-passwd -rfbauth -http
|
|
-xrandr -rotate -noxdamage
|
|
-xkb -skip_lockkeys -nomodtweak
|
|
-repeat -cursor -wmdt
|
|
-nowireframe -ncache_cr -speeds
|
|
|
|
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-cmdline-opts
|
|
}
|
|
# In Auto Port put a starting port for x11vnc to try autoprobing
|
|
# instead of the default 5900. It starts at the value you supply and
|
|
# works upward until a free one is found. (x11vnc 0.9.3 or later).
|
|
|
|
.x11v.f.t insert end $msg
|
|
|
|
frame .x11v.c
|
|
label .x11v.c.l -width 10 -anchor w -text "Options:"
|
|
entry .x11v.c.e -textvariable ts_x11vnc_opts
|
|
pack .x11v.c.l -side left
|
|
pack .x11v.c.e -side left -expand 1 -fill x
|
|
|
|
frame .x11v.c2
|
|
label .x11v.c2.l -width 10 -anchor w -text "Full Path:"
|
|
entry .x11v.c2.e -textvariable ts_x11vnc_path
|
|
pack .x11v.c2.l -side left
|
|
pack .x11v.c2.e -side left -expand 1 -fill x
|
|
|
|
# frame .x11v.c3
|
|
# label .x11v.c3.l -width 10 -anchor w -text "Auto Port:"
|
|
# entry .x11v.c3.e -textvariable ts_x11vnc_autoport
|
|
# pack .x11v.c3.l -side left
|
|
# pack .x11v.c3.e -side left -expand 1 -fill x
|
|
|
|
frame .x11v.c4
|
|
label .x11v.c4.l -width 10 -anchor w -text "Port Redirs:"
|
|
entry .x11v.c4.e -textvariable additional_port_redirs_list
|
|
pack .x11v.c4.l -side left
|
|
pack .x11v.c4.e -side left -expand 1 -fill x
|
|
|
|
button .x11v.cancel -text "Cancel" -command {destroy .x11v; set choose_x11vnc_opts 0}
|
|
bind .x11v <Escape> {destroy .x11v; set choose_x11vnc_opts 0}
|
|
wm protocol .x11v WM_DELETE_WINDOW {destroy .x11v; set choose_x11vnc_opts 0}
|
|
button .x11v.done -text "Done" -command {destroy .x11v; set choose_x11vnc_opts 1;
|
|
if {$additional_port_redirs_list != ""} {set additional_port_redirs 1} else {set additional_port_redirs 0}}
|
|
|
|
# pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c3 .x11v.c2 .x11v.c -side bottom -fill x
|
|
pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c2 .x11v.c -side bottom -fill x
|
|
pack .x11v.f -side top -fill both -expand 1
|
|
|
|
center_win .x11v
|
|
focus .x11v.c.e
|
|
}
|
|
|
|
|
|
proc ts_filexfer_dialog {} {
|
|
|
|
toplev .xfer
|
|
wm title .xfer "File Transfer"
|
|
global choose_filexfer ts_filexfer
|
|
|
|
scroll_text .xfer.f 70 13
|
|
|
|
set msg {
|
|
x11vnc supports both the UltraVNC and TightVNC file transfer
|
|
extensions. On Windows both viewers support their file transfer
|
|
protocol. On Unix only the SSVNC VNC Viewer can do filexfer; it
|
|
supports the UltraVNC flavor via a Java helper program (and so
|
|
java(1) is required on the viewer-side).
|
|
|
|
Choose the one you want based on VNC viewer you will use.
|
|
The defaults for the SSVNC viewer package are TightVNC on
|
|
Windows and UltraVNC on Unix.
|
|
|
|
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-filexfer
|
|
}
|
|
.xfer.f.t insert end $msg
|
|
|
|
global is_windows
|
|
if {$ts_filexfer == ""} {
|
|
if {$is_windows} {
|
|
set ts_filexfer "tight"
|
|
} else {
|
|
set ts_filexfer "ultra"
|
|
}
|
|
}
|
|
|
|
frame .xfer.c
|
|
radiobutton .xfer.c.tight -text "TightVNC" -variable ts_filexfer -value "tight" -relief ridge
|
|
radiobutton .xfer.c.ultra -text "UltraVNC" -variable ts_filexfer -value "ultra" -relief ridge
|
|
|
|
pack .xfer.c.ultra .xfer.c.tight -side left -fill x -expand 1
|
|
|
|
button .xfer.cancel -text "Cancel" -command {destroy .xfer; set choose_filexfer 0}
|
|
bind .xfer <Escape> {destroy .xfer; set choose_filexfer 0}
|
|
wm protocol .xfer WM_DELETE_WINDOW {destroy .xfer; set choose_filexfer 0}
|
|
button .xfer.done -text "Done" -command {destroy .xfer; set choose_filexfer 1}
|
|
|
|
pack .xfer.done .xfer.cancel -side bottom -fill x
|
|
pack .xfer.c -side bottom -fill x -expand 1
|
|
pack .xfer.f -side top -fill both -expand 1
|
|
|
|
center_win .xfer
|
|
}
|
|
|
|
proc ts_cups_dialog {} {
|
|
|
|
toplev .cups
|
|
wm title .cups "CUPS and SMB Printing"
|
|
global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc
|
|
global cups_local_smb_server cups_remote_smb_port
|
|
|
|
set h 30
|
|
if [small_height] {
|
|
set h 24
|
|
}
|
|
scroll_text .cups.f 80 $h
|
|
|
|
|
|
set msg {
|
|
This method requires a working CUPS Desktop setup on the remote side
|
|
of the connection and working CUPS (or possibly Windows SMB or IPP)
|
|
printing on the local viewer-side of the connection.
|
|
|
|
For CUPS printing redirection to work properly, you MUST enable it for
|
|
the connection that *creates* your terminal services X session (i.e. the
|
|
first connection.) You cannot retroactively enable CUPS redirection
|
|
on an already existing terminal services X session. (See CUPS printing
|
|
for normal SSVNC mode for how you might do that.)
|
|
|
|
Enter the VNC Viewer side (i.e. where you are sitting) CUPS server
|
|
under "Local CUPS Server". Use "localhost:631" if there is one
|
|
on your viewer machine (normally the case if you set up a printer
|
|
on your unix or macosx system), or, e.g., "my-print-srv:631" for a
|
|
nearby CUPS print server. Note that 631 is the default CUPS port.
|
|
|
|
(On MacOSX it seems better to use "127.0.0.1" instead of "localhost".)
|
|
|
|
The SSVNC Terminal Services created remote Desktop session will have
|
|
the variables CUPS_SERVER and IPP_PORT set so all printing applications
|
|
will be redirected to your local CUPS server. So your locally available
|
|
printers should appear in the remote print dialogs.
|
|
|
|
|
|
Windows/SMB Printers: Under "Local SMB Print Server" you can set a
|
|
port redirection for a Windows (non-CUPS) SMB printer. If localhost:139
|
|
does not work, try the literal string "IP:139", or use the known value
|
|
of the IP address manually. 139 is the default SMB port; nowadays 445
|
|
might be a better possibility.
|
|
|
|
For Windows/SMB Printers if there is no local CUPS print server, it is
|
|
usually a very good idea to make the CUPS Server setting EMPTY (to avoid
|
|
desktop apps trying incessantly to reach the nonexistent CUPS server.)
|
|
|
|
On the remote side, in the Desktop session the variables $SMB_SERVER,
|
|
$SMB_HOST, and $SMB_PORT will be set for you to use.
|
|
|
|
Unfortunately, printing to Windows may only ve partially functional due
|
|
to the general lack PostScript support on Windows.
|
|
|
|
If you have print admin permission on the remote machine you can
|
|
configure CUPS to know about your Windows printer via lpadmin(8) or
|
|
a GUI tool. You give it the URI:
|
|
|
|
smb://localhost:port/printername
|
|
|
|
or possibly:
|
|
|
|
smb://localhost:port/computer/printername
|
|
|
|
"port" will be found in the $SMB_PORT. You also need to identify
|
|
the printer type. NOTE: You will leave "Local CUPS Server" blank in
|
|
this case. The smbspool(1) command should also work as well, at least
|
|
for PostScript printers.
|
|
|
|
A similar thing can be done with CUPS printers if you are having problems
|
|
with the above default mechanism. Use
|
|
|
|
http://localhost:port/printers/printername
|
|
|
|
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
|
|
}
|
|
|
|
# The "Manage 'ServerName' in .cups/client.conf for me" setting is usually
|
|
# NOT needed unless you are using Terminal Services to connect to an
|
|
# existing Session that did NOT have CUPS print redirection set at session
|
|
# start time (i.e. IPP_PORT and CUPS_SERVER were not set up). In that
|
|
# case, select this option as a workaround: NOTE that the client.conf
|
|
# setting will REDIRECT ALL PRINTING for apps with the same $HOME/.cups
|
|
# directory (which you probably do not want), however it will be reset
|
|
# when the SSVNC viewer disconnects.
|
|
|
|
.cups.f.t insert end $msg
|
|
|
|
global uname
|
|
if {$cups_local_server == ""} {
|
|
if {$uname == "Darwin"} {
|
|
set cups_local_server "127.0.0.1:631"
|
|
} else {
|
|
set cups_local_server "localhost:631"
|
|
}
|
|
}
|
|
if {$cups_remote_port == ""} {
|
|
set cups_remote_port [expr "6731 + int(1000 * rand())"]
|
|
}
|
|
if {$cups_local_smb_server == ""} {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
set cups_local_smb_server "IP:139"
|
|
} elseif {$uname == "Darwin"} {
|
|
set cups_local_smb_server "127.0.0.1:139"
|
|
} else {
|
|
set cups_local_smb_server "localhost:139"
|
|
}
|
|
}
|
|
if {$cups_remote_smb_port == ""} {
|
|
set cups_remote_smb_port [expr "7731 + int(1000 * rand())"]
|
|
}
|
|
|
|
frame .cups.serv
|
|
label .cups.serv.l -anchor w -text "Local CUPS Server: "
|
|
entry .cups.serv.e -width 40 -textvariable cups_local_server
|
|
pack .cups.serv.e -side right
|
|
pack .cups.serv.l -side left -expand 1 -fill x
|
|
|
|
frame .cups.smbs
|
|
label .cups.smbs.l -anchor w -text "Local SMB Print Server: "
|
|
entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server
|
|
pack .cups.smbs.e -side right
|
|
pack .cups.smbs.l -side left -expand 1 -fill x
|
|
|
|
# not working with x11vnc:
|
|
checkbutton .cups.cupsrc -anchor w -variable ts_cups_manage_rcfile -text \
|
|
"Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me"
|
|
|
|
button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0}
|
|
bind .cups <Escape> {destroy .cups; set use_cups 0}
|
|
wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0}
|
|
button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}}
|
|
|
|
pack .cups.done .cups.cancel .cups.smbs .cups.serv -side bottom -fill x
|
|
pack .cups.f -side top -fill both -expand 1
|
|
|
|
center_win .cups
|
|
focus .cups.serv.e
|
|
}
|
|
|
|
|
|
proc cups_dialog {} {
|
|
|
|
toplev .cups
|
|
wm title .cups "CUPS Tunnelling"
|
|
global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc
|
|
global cups_local_smb_server cups_remote_smb_port
|
|
global ts_only
|
|
if {$ts_only} {
|
|
ts_cups_dialog
|
|
return
|
|
}
|
|
|
|
global uname
|
|
set h 33
|
|
if [small_height] {
|
|
set h 17
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 24
|
|
}
|
|
scroll_text .cups.f 80 $h
|
|
|
|
|
|
set msg {
|
|
CUPS Printing requires SSH be used to set up the CUPS Print service TCP
|
|
port redirection. This will be either of the "Use SSH" or "SSH+SSL" modes.
|
|
NOTE: For pure SSL tunnelling it currently will not work.
|
|
|
|
This method requires working CUPS software setups on BOTH the remote
|
|
and local sides of the connection.
|
|
|
|
If the remote VNC server is Windows you probably cannot SSH into it
|
|
anyway... If you can, you will still need to set up a special printer
|
|
TCP port redirection on your own. Perhaps adding and configuring a
|
|
"Unix Printer" under Windows (like Method #2 below) will work.
|
|
|
|
If the local machine (SSVNC side) is Windows, see the bottom of this
|
|
help for redirecting to SMB printers.
|
|
|
|
If the remote VNC server is Mac OS X this method may or may not work.
|
|
Sometimes applications need to be restarted to get them to notice the
|
|
new printers. Adding and configuring a special "Unix Printer",
|
|
(Method #2) below, might yield more reliable results at the cost of
|
|
additional setup and permissions.
|
|
|
|
For Unix/Linux remote VNC servers, applications may also need to be
|
|
restarted to notice the new printers. The only case known to work
|
|
well is the one where the remote side has no CUPS printers configured.
|
|
As mentioned above, see Method #2 for another method.
|
|
|
|
*************************************************************************
|
|
*** Directions:
|
|
|
|
You choose your own remote CUPS redir port below under "Use Remote
|
|
CUPS Port". 6631 is our default and is used in the examples below.
|
|
Use it or some random value greater than 1024. Note that the standard
|
|
CUPS server port is 631.
|
|
|
|
The port you choose must be unused on the VNC server machine (it is NOT
|
|
checked for you). Print requests connecting to it are redirected to
|
|
your local VNC viewer-side CUPS server through the SSH tunnel.
|
|
|
|
(Note: root SSH login permission is needed for ports less than 1024,
|
|
e.g. 631; this is not recommended, use something around 6631 instead).
|
|
|
|
Then enter the VNC Viewer side (i.e. where you are sitting) CUPS server
|
|
into "Local CUPS Server". A good choice is the default "localhost:631"
|
|
if there is a cups server on your viewer machine (this is usually the case
|
|
if you have set up a printer). Otherwise enter, e.g., "my-print-srv:631"
|
|
for your nearby (viewer-side) CUPS print server.
|
|
|
|
|
|
The "Manage 'ServerName' in the $HOME/.cups/client.conf file for me"
|
|
setting below is enabled by default. It should handle most situations.
|
|
|
|
What it does is modify the .cups/client.conf file on the VNC server-side
|
|
to redirect the print requests while the SSVNC viewer is connected. When
|
|
SSVNC disconnects .cups/client.conf is restored to its previous setting.
|
|
|
|
If, for some reason, the SSVNC CUPS script fails to restore this file
|
|
after SSVNC disconnects, run this command on the remote machine:
|
|
|
|
cp $HOME/.cups/client.conf.back $HOME/.cups/client.conf
|
|
|
|
to regain your initial printing configuration.
|
|
|
|
|
|
You can also use CUPS on the VNC server-side to redirect to Windows
|
|
(SMB) printers. See the additional info for Windows Printing at the
|
|
bottom of this help.
|
|
|
|
|
|
In case the default method (automatic .cups/client.conf modification)
|
|
fails, we describe below all of the possible methods that can be tried.
|
|
|
|
As noted above, you may need to restart applications for them to notice
|
|
the new printers or for them to revert to the original printers. If this
|
|
is not acceptable, consider Method #2 below if you have the permission
|
|
and ability to alter the print queues for this.
|
|
|
|
|
|
*************************************************************************
|
|
*** Method #1: Manually create or edit the file $HOME/.cups/client.conf
|
|
on the VNC server side by putting in something like this in it:
|
|
|
|
ServerName localhost:6631
|
|
|
|
based on the port you set in this dialog's entry box.
|
|
|
|
After the remote VNC Connection is finished, to go back to the non-SSH
|
|
tunnelled CUPS server and either remove the client.conf file or comment
|
|
out the ServerName line. This restores the normal CUPS server for
|
|
you on the remote VNC server machine.
|
|
|
|
Select "Manage 'ServerName' in the $HOME/.cups/client.conf file for me"
|
|
to do this editing of the VNC server-side CUPS config file for you
|
|
automatically. NOTE: It is now on by default (deselect it if you want
|
|
to manage the file manually; e.g. you print through the tunnel only very
|
|
rarely, or often print locally when the tunnel is up, etc.)
|
|
|
|
Select "Pass -env FD_CUPS=<Port> to x11vnc command line" if you are
|
|
starting x11vnc as the Remote SSH Command, and x11vnc is running in
|
|
-create mode (i.e. FINDCREATEDISPLAY). That way, when your X session
|
|
is created IPP_PORT will be set correctly for the entire session.
|
|
This is the mode used for 'Terminal Services' printing.
|
|
|
|
NOTE: You probably would never select both of the above two options
|
|
at the same time, since they conflict with each other to some degree.
|
|
|
|
|
|
*************************************************************************
|
|
*** Method #2: If you have admin permission on the VNC Server machine
|
|
you can likely "Add a Printer" via a GUI dialog, a Wizard, CUPS Web
|
|
interface (i.e. http://localhost:631/), lpadmin(8), etc.
|
|
|
|
You will need to tell the dialog that the network printer located
|
|
is at, e.g., localhost:6631, and anything else needed to identify
|
|
the printer (type, model, etc). NOTE: sometimes it is best to set
|
|
the model/type as "Generic / Postscript Printer" to avoid problems
|
|
with garbage being printed out.
|
|
|
|
For the URI to use, we have successfully used ones like this with CUPS:
|
|
|
|
http://localhost:6631/printers/Deskjet-3840
|
|
ipp://localhost:6631/printers/Deskjet-3840
|
|
|
|
for an HP Deskjet-3840 printer. See the CUPS documentation for more
|
|
about the URI syntax and pathname.
|
|
|
|
This mode makes the client.conf ServerName parameter unnecessary
|
|
(BE SURE TO DISABLE the "Manage 'ServerName' ... for me" option.)
|
|
|
|
|
|
*************************************************************************
|
|
*** Method #3: Restarting individual applications with the IPP_PORT
|
|
set will enable redirected printing for them, e.g.:
|
|
|
|
env IPP_PORT=6631 firefox
|
|
|
|
If you can only get this method to work, an extreme application would
|
|
be to run the whole desktop, e.g. "env IPP_PORT=6631 gnome-session", but
|
|
then you would need some sort of TCP redirector (ssh -L comes to mind),
|
|
to direct it to 631 when not connected remotely.
|
|
|
|
|
|
*************************************************************************
|
|
*** Windows/SMB Printers: Under "Local SMB Print Server" you can set
|
|
a port redirection for a Windows (non-CUPS) SMB printer. E.g. port
|
|
6632 -> localhost:139.
|
|
|
|
If localhost:139 does not work, try the literal string "IP:139", or
|
|
insert the actual IP address manually. NOTE: Nowadays on Windows port
|
|
445 might be a better choice.
|
|
|
|
For Windows printers, if there is no local CUPS print server, set the
|
|
'Local CUPS Server' and 'Use Remote CUPS Port' to be EMPTY (to avoid
|
|
desktop apps trying incessantly to reach the nonexistent CUPS server.)
|
|
|
|
You must enable Sharing for your local Windows Printer. Use Windows
|
|
Printer configuration dialogs to do this.
|
|
|
|
Next, you need to have sudo or print admin permission so that you can
|
|
configure the *remote* CUPS to know about this Windows printer via
|
|
lpadmin(8) or GUI Printer Configuration dialog, etc (Method #2 above).
|
|
You basically give it the URI:
|
|
|
|
smb://localhost:6632/printername
|
|
|
|
For example, we have had success with GNOME CUPS printing configuration
|
|
using:
|
|
|
|
smb://localhost:6632/HPOffice
|
|
smb://localhost:6632/COMPUTERNAME/HPOffice
|
|
|
|
where "HPOffice" was the name Windows shares the printer as.
|
|
|
|
Also with this SMB port redir mode, as a last resort you can often print
|
|
using the smbspool(8) program like this:
|
|
|
|
smbspool smb://localhost:6632/printer job user title 1 "" myfile.ps
|
|
|
|
You could put this in a script. For this URI, it appears only the number
|
|
of copies ("1" above) and the file itself are important.
|
|
|
|
If on the local (SSVNC viewer) side there is some nearby CUPS print server
|
|
that knows about your Windows printer, you might have better luck with
|
|
that instead of using SMB. Set 'Local CUPS Server' to it.
|
|
|
|
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
|
|
}
|
|
.cups.f.t insert end $msg
|
|
|
|
global uname
|
|
set something_set 0
|
|
|
|
if {$cups_local_server != ""} {
|
|
set something_set 1
|
|
}
|
|
if {$cups_local_smb_server != ""} {
|
|
set something_set 1
|
|
}
|
|
|
|
if {$cups_local_server == "" && ! $something_set} {
|
|
if {$uname == "Darwin"} {
|
|
set cups_local_server "127.0.0.1:631"
|
|
} else {
|
|
set cups_local_server "localhost:631"
|
|
}
|
|
}
|
|
if {$cups_remote_port == "" && ! $something_set} {
|
|
set cups_remote_port "6631"
|
|
}
|
|
if {$cups_local_smb_server == "" && ! $something_set} {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
set cups_local_smb_server "IP:139"
|
|
} elseif {$uname == "Darwin"} {
|
|
set cups_local_smb_server "127.0.0.1:139"
|
|
} else {
|
|
set cups_local_smb_server "localhost:139"
|
|
}
|
|
}
|
|
if {$cups_remote_smb_port == "" && ! $something_set} {
|
|
set cups_remote_smb_port "6632"
|
|
}
|
|
|
|
frame .cups.serv
|
|
label .cups.serv.l -anchor w -text "Local CUPS Server: "
|
|
entry .cups.serv.e -width 40 -textvariable cups_local_server
|
|
pack .cups.serv.e -side right
|
|
pack .cups.serv.l -side left -expand 1 -fill x
|
|
|
|
frame .cups.port
|
|
label .cups.port.l -anchor w -text "Use Remote CUPS Port:"
|
|
entry .cups.port.e -width 40 -textvariable cups_remote_port
|
|
pack .cups.port.e -side right
|
|
pack .cups.port.l -side left -expand 1 -fill x
|
|
|
|
frame .cups.smbs
|
|
label .cups.smbs.l -anchor w -text "Local SMB Print Server: "
|
|
entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server
|
|
pack .cups.smbs.e -side right
|
|
pack .cups.smbs.l -side left -expand 1 -fill x
|
|
|
|
frame .cups.smbp
|
|
label .cups.smbp.l -anchor w -text "Use Remote SMB Print Port:"
|
|
entry .cups.smbp.e -width 40 -textvariable cups_remote_smb_port
|
|
pack .cups.smbp.e -side right
|
|
pack .cups.smbp.l -side left -expand 1 -fill x
|
|
|
|
checkbutton .cups.cupsrc -anchor w -variable cups_manage_rcfile -text \
|
|
"Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me"
|
|
|
|
checkbutton .cups.x11vnc -anchor w -variable cups_x11vnc -text \
|
|
"Pass -env FD_CUPS=<Port> to x11vnc command line."
|
|
|
|
button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0}
|
|
bind .cups <Escape> {destroy .cups; set use_cups 0}
|
|
wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0}
|
|
button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}}
|
|
|
|
button .cups.guess -text "Help me decide ..." -command {}
|
|
.cups.guess configure -state disabled
|
|
|
|
pack .cups.done .cups.cancel .cups.guess .cups.x11vnc .cups.cupsrc .cups.smbp .cups.smbs .cups.port .cups.serv -side bottom -fill x
|
|
pack .cups.f -side top -fill both -expand 1
|
|
|
|
center_win .cups
|
|
focus .cups.serv.e
|
|
}
|
|
|
|
proc ts_sound_dialog {} {
|
|
|
|
global is_windows
|
|
global ts_only
|
|
|
|
toplev .snd
|
|
wm title .snd "Sound Tunnelling"
|
|
|
|
scroll_text .snd.f 80 21
|
|
|
|
set msg {
|
|
Your remote Desktop will be started in an Enlightenment Sound Daemon
|
|
(ESD) environment (esddsp(1), which must be installed on the remote
|
|
machine), and a local ESD sound daemon (esd(1)) will be started to
|
|
play the sounds for you to hear.
|
|
|
|
In the entry box below you can choose the port that the local esd
|
|
will use to listen on. The default ESD port is 16001. You will
|
|
need to choose different values if you will have more than one esd
|
|
running locally.
|
|
|
|
The command run (with port replaced by your choice) will be:
|
|
|
|
%RCMD
|
|
|
|
Note: Unfortunately not all applications work with ESD.
|
|
And esd's LD_PRELOAD is broken on 64+32bit Linux (x86_64).
|
|
And so this mode is not working well currently...
|
|
|
|
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
|
|
}
|
|
|
|
|
|
global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd
|
|
global sound_daemon_local_start sound_daemon_local_kill
|
|
|
|
set sound_daemon_local_start 1
|
|
set sound_daemon_local_kill 1
|
|
|
|
if {$sound_daemon_remote_port == ""} {
|
|
set sound_daemon_remote_port 16010
|
|
}
|
|
if {$sound_daemon_local_port == ""} {
|
|
set sound_daemon_local_port 16010
|
|
}
|
|
|
|
if {$sound_daemon_local_cmd == ""} {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
|
|
} else {
|
|
set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
|
|
}
|
|
}
|
|
regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd
|
|
|
|
regsub {%RCMD} $msg $sound_daemon_local_cmd msg
|
|
.snd.f.t insert end $msg
|
|
|
|
frame .snd.lport
|
|
label .snd.lport.l -anchor w -text "Local Sound Port: "
|
|
entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port
|
|
pack .snd.lport.e -side right
|
|
pack .snd.lport.l -side left -expand 1 -fill x
|
|
|
|
button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0}
|
|
bind .snd <Escape> {destroy .snd; set use_sound 0}
|
|
wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0}
|
|
button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}}
|
|
bind .snd.lport.e <Return> {destroy .snd; if {$use_sound} {set_ssh}}
|
|
|
|
pack .snd.done .snd.cancel .snd.lport -side bottom -fill x
|
|
pack .snd.f -side bottom -fill both -expand 1
|
|
|
|
center_win .snd
|
|
focus .snd.lport.e
|
|
}
|
|
|
|
proc sound_dialog {} {
|
|
|
|
global is_windows
|
|
global ts_only
|
|
if {$ts_only} {
|
|
ts_sound_dialog;
|
|
return
|
|
}
|
|
|
|
toplev .snd
|
|
wm title .snd "ESD/ARTSD Sound Tunnelling"
|
|
|
|
global uname
|
|
set h 28
|
|
if [small_height] {
|
|
set h 14
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 20
|
|
}
|
|
scroll_text .snd.f 80 $h
|
|
|
|
set msg {
|
|
Sound tunnelling to a sound daemon requires SSH be used to set up the
|
|
service port redirection. This will be either of the "Use SSH" or
|
|
"SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work.
|
|
|
|
This method requires working Sound daemon (e.g. ESD or ARTSD) software
|
|
setups on BOTH the remote and local sides of the connection.
|
|
|
|
Often this means you want to run your ENTIRE remote desktop with ALL
|
|
applications instructed to use the sound daemon's network port. E.g.
|
|
|
|
esddsp -s localhost:16001 startkde
|
|
esddsp -s localhost:16001 gnome-session
|
|
|
|
and similarly for artsdsp, etc. You put this in your ~/.xession,
|
|
or other startup file. This is non standard. If you do not want to
|
|
do this you still can direct *individual* sound applications through
|
|
the tunnel, for example "esddsp -s localhost:16001 soundapp", where
|
|
"soundapp" is some application that makes noise (say xmms or mpg123).
|
|
|
|
Select "Pass -env FD_ESD=<Port> to x11vnc command line." if you are
|
|
starting x11vnc as the Remote SSH Command, and x11vnc is running in
|
|
-create mode (i.e. FINDCREATEDISPLAY). That way, your X session is
|
|
started via "esddsp -s ... <session>" and the ESD variables will be
|
|
set correctly for the entire session. (This mode make most sense for
|
|
a virtual, e.g. Xvfb or Xdummy session, not one a physical display).
|
|
|
|
Also, usually the remote Sound daemon must be killed BEFORE the SSH port
|
|
redir is established (because it is listening on the port we want to use
|
|
for the SSH redir), and, presumably, restarted when the VNC connection
|
|
finished.
|
|
|
|
One may also want to start and kill a local sound daemon that will
|
|
play the sound received over the network on the local machine.
|
|
|
|
You can indicate the remote and local Sound daemon commands below and
|
|
how they should be killed and/or restart. Some examples:
|
|
|
|
esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1
|
|
artsd -n -p 7265 -F 10 -S 4096 -n -s 5 -m artsmessage -l 3 -f
|
|
|
|
or you can leave some or all blank and kill/start them manually.
|
|
|
|
For convenience, a Windows port of ESD is provided in the util/esound
|
|
directory, and so this might work for a Local command:
|
|
|
|
esound\esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1
|
|
|
|
NOTE: If you indicate "Remote Sound daemon: Kill at start." below,
|
|
then THERE WILL BE TWO SSH'S: THE FIRST ONE TO KILL THE DAEMON.
|
|
So you may need to supply TWO SSH PASSWORDS, unless you are using
|
|
something like ssh-agent(1), the Putty PW setting, etc.
|
|
|
|
You will also need to supply the remote and local sound ports for
|
|
the SSH redirs. For esd the default port is 16001, but you can choose
|
|
another one if you prefer.
|
|
|
|
For "Local Sound Port" you can also supply "host:port" instead of just
|
|
a numerical port to specify non-localhost connections, e.g. to another
|
|
nearby machine.
|
|
|
|
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
|
|
}
|
|
.snd.f.t insert end $msg
|
|
|
|
global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd
|
|
if {$sound_daemon_remote_port == ""} {
|
|
set sound_daemon_remote_port 16001
|
|
}
|
|
if {$sound_daemon_local_port == ""} {
|
|
set sound_daemon_local_port 16001
|
|
}
|
|
|
|
if {$sound_daemon_local_cmd == ""} {
|
|
global is_windows
|
|
if {$is_windows} {
|
|
set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
|
|
} else {
|
|
set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
|
|
}
|
|
regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd
|
|
}
|
|
|
|
|
|
frame .snd.remote
|
|
label .snd.remote.l -anchor w -text "Remote Sound daemon cmd: "
|
|
entry .snd.remote.e -width 45 -textvariable sound_daemon_remote_cmd
|
|
pack .snd.remote.e -side right
|
|
pack .snd.remote.l -side left -expand 1 -fill x
|
|
|
|
frame .snd.local
|
|
label .snd.local.l -anchor w -text "Local Sound daemon cmd: "
|
|
entry .snd.local.e -width 45 -textvariable sound_daemon_local_cmd
|
|
pack .snd.local.e -side right
|
|
pack .snd.local.l -side left -expand 1 -fill x
|
|
|
|
frame .snd.rport
|
|
label .snd.rport.l -anchor w -text "Remote Sound Port: "
|
|
entry .snd.rport.e -width 45 -textvariable sound_daemon_remote_port
|
|
pack .snd.rport.e -side right
|
|
pack .snd.rport.l -side left -expand 1 -fill x
|
|
|
|
frame .snd.lport
|
|
label .snd.lport.l -anchor w -text "Local Sound Port: "
|
|
entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port
|
|
pack .snd.lport.e -side right
|
|
pack .snd.lport.l -side left -expand 1 -fill x
|
|
|
|
|
|
checkbutton .snd.sdk -anchor w -variable sound_daemon_kill -text \
|
|
"Remote Sound daemon: Kill at start."
|
|
|
|
checkbutton .snd.sdr -anchor w -variable sound_daemon_restart -text \
|
|
"Remote Sound daemon: Restart at end."
|
|
|
|
checkbutton .snd.sdsl -anchor w -variable sound_daemon_local_start -text \
|
|
"Local Sound daemon: Run at start."
|
|
|
|
checkbutton .snd.sdkl -anchor w -variable sound_daemon_local_kill -text \
|
|
"Local Sound daemon: Kill at end."
|
|
|
|
checkbutton .snd.x11vnc -anchor w -variable sound_daemon_x11vnc -text \
|
|
"Pass -env FD_ESD=<Port> to x11vnc command line."
|
|
|
|
button .snd.guess -text "Help me decide ..." -command {}
|
|
.snd.guess configure -state disabled
|
|
|
|
global is_win9x
|
|
if {$is_win9x} {
|
|
.snd.local.e configure -state disabled
|
|
.snd.local.l configure -state disabled
|
|
.snd.sdsl configure -state disabled
|
|
.snd.sdkl configure -state disabled
|
|
}
|
|
|
|
button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0}
|
|
bind .snd <Escape> {destroy .snd; set use_sound 0}
|
|
wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0}
|
|
button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}}
|
|
|
|
pack .snd.done .snd.cancel .snd.guess .snd.x11vnc .snd.sdkl .snd.sdsl .snd.sdr .snd.sdk .snd.lport .snd.rport \
|
|
.snd.local .snd.remote -side bottom -fill x
|
|
pack .snd.f -side bottom -fill both -expand 1
|
|
|
|
center_win .snd
|
|
focus .snd.remote.e
|
|
}
|
|
|
|
# Share ideas.
|
|
#
|
|
# Unix:
|
|
#
|
|
# if type smbclient
|
|
# first parse smbclient -L localhost -N
|
|
# and/or smbclient -L `hostname` -N
|
|
# Get Sharenames and Servers and Domain.
|
|
#
|
|
# loop over servers, doing smbclient -L server -N
|
|
# pile this into a huge list, sep by disk and printers.
|
|
#
|
|
# WinXP:
|
|
#
|
|
# parse "NET VIEW" output similarly.
|
|
#
|
|
# Have checkbox for each disk. Set default root to /var/tmp/${USER}-mnts
|
|
# Let them change that at once and have it populate.
|
|
#
|
|
# use //hostname/share /var/tmp/runge-mnts/hostname/share
|
|
#
|
|
#
|
|
# Printers, hmmm. Can't add to remote cups list... I guess have the list
|
|
# ready for CUPS dialog to suggest which SMB servers they want to redirect
|
|
# to...
|
|
|
|
proc get_hostname {} {
|
|
global is_windows is_win9x
|
|
set str ""
|
|
if {$is_windows} {
|
|
if {1} {
|
|
catch {set str [exec hostname]}
|
|
regsub -all {[\r]} $str "" str
|
|
} else {
|
|
catch {set str [exec net config]}
|
|
if [regexp -nocase {Computer name[ \t]+\\\\([^ \t]+)} $str mv str] {
|
|
;
|
|
} else {
|
|
set str ""
|
|
}
|
|
}
|
|
} else {
|
|
catch {set str [exec hostname]}
|
|
}
|
|
set str [string trim $str]
|
|
return $str
|
|
}
|
|
|
|
proc smb_list_windows {smbhost} {
|
|
global smb_local smb_local_hosts smb_this_host
|
|
global is_win9x
|
|
set dbg 0
|
|
|
|
set domain ""
|
|
|
|
if {$is_win9x} {
|
|
# exec net view ... doesn't work.
|
|
set smb_this_host "unknown"
|
|
return
|
|
}
|
|
|
|
set this_host [get_hostname]
|
|
set This_host [string toupper $this_host]
|
|
set smb_this_host $This_host
|
|
|
|
if {$smbhost == $smb_this_host} {
|
|
catch {set out0 [exec net view]}
|
|
regsub -all {[\r]} $out0 "" out0
|
|
foreach line [split $out0 "\n"] {
|
|
if [regexp -nocase {in workgroup ([^ \t]+)} $line mv wg] {
|
|
regsub -all {[.]} $wg "" wg
|
|
set domain $wg
|
|
} elseif [regexp {^\\\\([^ \t]+)[ \t]*(.*)} $line mv host comment] {
|
|
set smb_local($smbhost:server:$host) $comment
|
|
}
|
|
}
|
|
}
|
|
|
|
set out1 ""
|
|
set h "\\\\$smbhost"
|
|
catch {set out1 [exec net view $h]}
|
|
regsub -all {[\r]} $out1 "" out1
|
|
|
|
if {$dbg} {puts "SMBHOST: $smbhost"}
|
|
|
|
set mode ""
|
|
foreach line [split $out1 "\n"] {
|
|
if [regexp {^[ \t]*---} $line] {
|
|
continue
|
|
}
|
|
if [regexp -nocase {The command} $line] {
|
|
continue
|
|
}
|
|
if [regexp -nocase {Shared resources} $line] {
|
|
continue
|
|
}
|
|
if [regexp -nocase {^[ \t]*Share[ \t]*name} $line] {
|
|
set mode "shares"
|
|
continue
|
|
}
|
|
set line [string trim $line]
|
|
if {$line == ""} {
|
|
continue
|
|
}
|
|
if {$mode == "shares"} {
|
|
if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] {
|
|
if {$dbg} {
|
|
puts "SHR: $name"
|
|
puts "---: $type"
|
|
puts "---: $comment"
|
|
}
|
|
if [regexp -nocase {^Disk$} $type] {
|
|
set smb_local($smbhost:disk:$name) $comment
|
|
} elseif [regexp -nocase {^Print} $type] {
|
|
set smb_local($smbhost:printer:$name) $comment
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
set smb_local($smbhost:domain) $domain
|
|
}
|
|
|
|
proc smb_list_unix {smbhost} {
|
|
global smb_local smb_local_hosts smb_this_host
|
|
set smbclient [in_path smbclient]
|
|
if {[in_path smbclient] == ""} {
|
|
return ""
|
|
}
|
|
set dbg 0
|
|
|
|
set this_host [get_hostname]
|
|
set This_host [string toupper $this_host]
|
|
set smb_this_host $This_host
|
|
|
|
set out1 ""
|
|
catch {set out1 [exec smbclient -N -L $smbhost 2>@ stdout]}
|
|
|
|
if {$dbg} {puts "SMBHOST: $smbhost"}
|
|
if {$smbhost == $this_host || $smbhost == $This_host} {
|
|
if {$out1 == ""} {
|
|
catch {set out1 [exec smbclient -N -L localhost 2>@ stdout]}
|
|
}
|
|
}
|
|
|
|
set domain ""
|
|
set mode ""
|
|
foreach line [split $out1 "\n"] {
|
|
if [regexp {^[ \t]*---} $line] {
|
|
continue
|
|
}
|
|
if [regexp {Anonymous login} $line] {
|
|
continue
|
|
}
|
|
if {$domain == "" && [regexp {Domain=\[([^\]]+)\]} $line mv domain]} {
|
|
if {$dbg} {puts "DOM: $domain"}
|
|
continue
|
|
}
|
|
if [regexp {^[ \t]*Sharename} $line] {
|
|
set mode "shares"
|
|
continue
|
|
}
|
|
if [regexp {^[ \t]*Server} $line] {
|
|
set mode "server"
|
|
continue
|
|
}
|
|
if [regexp {^[ \t]*Workgroup} $line] {
|
|
set mode "workgroup"
|
|
continue
|
|
}
|
|
set line [string trim $line]
|
|
if {$mode == "shares"} {
|
|
if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] {
|
|
if {$dbg} {
|
|
puts "SHR: $name"
|
|
puts "---: $type"
|
|
puts "---: $comment"
|
|
}
|
|
if [regexp -nocase {^Disk$} $type] {
|
|
set smb_local($smbhost:disk:$name) $comment
|
|
} elseif [regexp -nocase {^Printer$} $type] {
|
|
set smb_local($smbhost:printer:$name) $comment
|
|
}
|
|
}
|
|
} elseif {$mode == "server"} {
|
|
if [regexp {^([^ \t]+)[ \t]*(.*)$} $line mv host comment] {
|
|
if {$dbg} {
|
|
puts "SVR: $host"
|
|
puts "---: $comment"
|
|
}
|
|
set smb_local($smbhost:server:$host) $comment
|
|
}
|
|
} elseif {$mode == "workgroup"} {
|
|
if [regexp {^([^ \t]+)[ \t]+(.*)$} $line mv work host] {
|
|
if {$dbg} {
|
|
puts "WRK: $work"
|
|
puts "---: $host"
|
|
}
|
|
if {$host != ""} {
|
|
set smb_local($smbhost:master:$work) $host
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
set smb_local($smbhost:domain) $domain
|
|
}
|
|
|
|
proc smb_list {} {
|
|
global is_windows smb_local smb_local_hosts
|
|
global smb_host_list
|
|
|
|
set smb_local(null) ""
|
|
|
|
if {! [info exists smb_host_list]} {
|
|
set smb_host_list ""
|
|
}
|
|
if [info exists smb_local] {
|
|
unset smb_local
|
|
}
|
|
if [info exists smb_local_hosts] {
|
|
unset smb_local_hosts
|
|
}
|
|
|
|
set this_host [get_hostname]
|
|
set this_host [string toupper $this_host]
|
|
if {$is_windows} {
|
|
smb_list_windows $this_host
|
|
} else {
|
|
smb_list_unix $this_host
|
|
}
|
|
set did($this_host) 1
|
|
set keys [array names smb_local]
|
|
foreach item [split $smb_host_list] {
|
|
if {$item != ""} {
|
|
set item [string toupper $item]
|
|
lappend keys "$this_host:server:$item"
|
|
}
|
|
}
|
|
foreach key $keys {
|
|
if [regexp "^$this_host:server:(.*)\$" $key mv host] {
|
|
if {$host == ""} {
|
|
continue
|
|
}
|
|
set smb_local_hosts($host) 1
|
|
if {! [info exists did($host)]} {
|
|
if {$is_windows} {
|
|
smb_list_windows $host
|
|
} else {
|
|
smb_list_unix $host
|
|
}
|
|
set did($host) 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc smb_check_selected {} {
|
|
global smbmount_exists smbmount_sumode
|
|
global smb_selected smb_selected_mnt smb_selected_cb smb_selected_en
|
|
|
|
set ok 0
|
|
if {$smbmount_exists && $smbmount_sumode != "dontknow"} {
|
|
set ok 1
|
|
}
|
|
set state disabled
|
|
if {$ok} {
|
|
set state normal
|
|
}
|
|
|
|
foreach cb [array names smb_selected_cb] {
|
|
catch {$cb configure -state $state}
|
|
}
|
|
foreach en [array names smb_selected_en] {
|
|
catch {$en configure -state $state}
|
|
}
|
|
}
|
|
|
|
proc make_share_widgets {w} {
|
|
|
|
set share_label $w.f.hl
|
|
catch {$share_label configure -text "Share Name: PROBING ..."}
|
|
update
|
|
|
|
smb_list
|
|
|
|
set saw_f 0
|
|
foreach child [winfo children $w] {
|
|
if {$child == "$w.f"} {
|
|
set saw_f 1
|
|
continue
|
|
}
|
|
catch {destroy $child}
|
|
}
|
|
|
|
set w1 47
|
|
set w2 44
|
|
|
|
if {! $saw_f} {
|
|
set wf $w.f
|
|
frame $wf
|
|
label $wf.hl -width $w1 -text "Share Name:" -anchor w
|
|
label $wf.hr -width $w2 -text " Mount Point:" -anchor w
|
|
|
|
pack $wf.hl $wf.hr -side left -expand 1
|
|
pack $wf -side top -fill x
|
|
|
|
.smbwiz.f.t window create end -window $w
|
|
}
|
|
|
|
global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt
|
|
global smb_selected_host smb_selected_name
|
|
global smb_selected_cb smb_selected_en
|
|
global smb_host_list
|
|
if [info exists smb_selected] {array unset smb_selected }
|
|
if [info exists smb_selected_mnt] {array unset smb_selected_mnt}
|
|
if [info exists smb_selected_cb] {array unset smb_selected_cb}
|
|
if [info exists smb_selected_en] {array unset smb_selected_en}
|
|
if [info exists smb_selected_host] {array unset smb_selected_host}
|
|
if [info exists smb_selected_name] {array unset smb_selected_name}
|
|
|
|
set hosts [list $smb_this_host]
|
|
lappend hosts [lsort [array names smb_local_hosts]]
|
|
|
|
set smb_host_list ""
|
|
set i 0
|
|
|
|
global smb_mount_prefix
|
|
set smb_mount_prefix "/var/tmp/%USER-mnts"
|
|
|
|
foreach host [lsort [array names smb_local_hosts]] {
|
|
|
|
if [info exists did($host)] {
|
|
continue
|
|
}
|
|
set did($host) 1
|
|
|
|
append smb_host_list "$host "
|
|
|
|
foreach key [lsort [array names smb_local]] {
|
|
if [regexp {^([^:]+):([^:]+):(.*)$} $key mv host2 type name] {
|
|
if {$host2 != $host} {
|
|
continue
|
|
}
|
|
if {$type != "disk"} {
|
|
continue
|
|
}
|
|
set wf $w.f$i
|
|
frame $wf
|
|
checkbutton $wf.c -anchor w -width $w1 -variable smb_selected($i) \
|
|
-text "//$host/$name" -relief ridge
|
|
if {! [info exists smb_selected($i)]} {
|
|
set smb_selected($i) 0
|
|
}
|
|
|
|
entry $wf.e -width $w2 -textvariable smb_selected_mnt($i)
|
|
set smb_selected_mnt($i) "$smb_mount_prefix/$host/$name"
|
|
|
|
set smb_selected_host($i) $host
|
|
set smb_selected_name($i) $name
|
|
|
|
set smb_selected_cb($wf.c) $i
|
|
set smb_selected_en($wf.e) $i
|
|
set comment $smb_local($key)
|
|
|
|
bind $wf.c <Enter> "$share_label configure -text {Share Name: $comment}"
|
|
bind $wf.c <Leave> "$share_label configure -text {Share Name:}"
|
|
|
|
$wf.c configure -state disabled
|
|
$wf.e configure -state disabled
|
|
|
|
pack $wf.c $wf.e -side left -expand 1
|
|
pack $wf -side top -fill x
|
|
incr i
|
|
}
|
|
}
|
|
}
|
|
if {$i == 0} {
|
|
global is_win9x
|
|
$share_label configure -text {Share Name: No SMB Share Hosts were found!}
|
|
if {$is_win9x} {
|
|
.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"
|
|
}
|
|
} else {
|
|
$share_label configure -text "Share Name: Found $i SMB Shares"
|
|
}
|
|
smb_check_selected
|
|
}
|
|
|
|
proc smb_help_me_decide {} {
|
|
global is_windows
|
|
global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt
|
|
global smb_selected_host smb_selected_name
|
|
global smb_selected_cb smb_selected_en
|
|
global smb_host_list
|
|
|
|
toplev .smbwiz
|
|
set title "SMB Filesystem Tunnelling -- Help Me Decide"
|
|
wm title .smbwiz $title
|
|
set id " "
|
|
|
|
set h 40
|
|
if [small_height] {
|
|
set h 30
|
|
}
|
|
scroll_text .smbwiz.f 100 $h
|
|
|
|
set msg {
|
|
For now you will have to verify the following information manually.
|
|
|
|
You can do this by either logging into the remote machine to find the info or asking the sysadmin for it.
|
|
|
|
}
|
|
|
|
if {! $is_windows} {
|
|
.smbwiz.f.t configure -font {Helvetica -12 bold}
|
|
}
|
|
.smbwiz.f.t insert end $msg
|
|
|
|
set w .smbwiz.f.t.f1
|
|
frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
|
|
|
|
.smbwiz.f.t insert end "\n"
|
|
|
|
.smbwiz.f.t insert end "1) Indicate the existence of the 'smbmount' command on the remote system:\n"
|
|
.smbwiz.f.t insert end "\n$id"
|
|
global smbmount_exists
|
|
set smbmount_exists 0
|
|
|
|
checkbutton $w.smbmount_exists -pady 1 -anchor w -variable smbmount_exists \
|
|
-text "Yes, the 'smbmount' command exists on the remote system." \
|
|
-command smb_check_selected
|
|
|
|
pack $w.smbmount_exists
|
|
.smbwiz.f.t window create end -window $w
|
|
|
|
.smbwiz.f.t insert end "\n\n\n"
|
|
|
|
set w .smbwiz.f.t.f2
|
|
frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
|
|
|
|
.smbwiz.f.t insert end "2) Indicate your authorization to run 'smbmount' on the remote system:\n"
|
|
.smbwiz.f.t insert end "\n$id"
|
|
global smbmount_sumode
|
|
set smbmount_sumode "dontknow"
|
|
|
|
radiobutton $w.dk -pady 1 -anchor w -variable smbmount_sumode -value dontknow \
|
|
-text "I do not know if I can mount SMB shares on the remote system via 'smbmount'" \
|
|
-command smb_check_selected
|
|
pack $w.dk -side top -fill x
|
|
|
|
radiobutton $w.su -pady 1 -anchor w -variable smbmount_sumode -value su \
|
|
-text "I know the Password to run commands as root on the remote system via 'su'" \
|
|
-command smb_check_selected
|
|
pack $w.su -side top -fill x
|
|
|
|
radiobutton $w.sudo -pady 1 -anchor w -variable smbmount_sumode -value sudo \
|
|
-text "I know the Password to run commands as root on the remote system via 'sudo'" \
|
|
-command smb_check_selected
|
|
pack $w.sudo -side top -fill x
|
|
|
|
radiobutton $w.ru -pady 1 -anchor w -variable smbmount_sumode -value none \
|
|
-text "I do not need to be root on the remote system to mount SMB shares via 'smbmount'" \
|
|
-command smb_check_selected
|
|
pack $w.ru -side top -fill x
|
|
|
|
.smbwiz.f.t window create end -window $w
|
|
|
|
global smb_wiz_done
|
|
set smb_wiz_done 0
|
|
|
|
button .smbwiz.cancel -text "Cancel" -command {set smb_wiz_done 1}
|
|
button .smbwiz.done -text "Done" -command {set smb_wiz_done 1}
|
|
pack .smbwiz.done -side bottom -fill x
|
|
pack .smbwiz.f -side top -fill both -expand 1
|
|
|
|
wm protocol .smbwiz WM_DELETE_WINDOW {set smb_wiz_done 1}
|
|
center_win .smbwiz
|
|
|
|
wm title .smbwiz "Searching for Local SMB shares..."
|
|
update
|
|
wm title .smbwiz $title
|
|
|
|
global smb_local smb_this_host
|
|
.smbwiz.f.t insert end "\n\n\n"
|
|
|
|
set w .smbwiz.f.t.f3
|
|
catch {destroy $w}
|
|
frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
|
|
|
|
.smbwiz.f.t insert end "3) Select SMB shares to mount and their mount point on the remote system:\n"
|
|
.smbwiz.f.t insert end "\n${id}"
|
|
|
|
make_share_widgets $w
|
|
|
|
.smbwiz.f.t insert end "\n(%USER will be expanded to the username on the remote system and %HOME the home directory)\n"
|
|
|
|
.smbwiz.f.t insert end "\n\n\n"
|
|
|
|
.smbwiz.f.t insert end "You can change the list of Local SMB hosts to probe and the mount point prefix here:\n"
|
|
.smbwiz.f.t insert end "\n$id"
|
|
set w .smbwiz.f.t.f4
|
|
frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
|
|
set wf .smbwiz.f.t.f4.f
|
|
frame $wf
|
|
label $wf.l -text "SMB Hosts: " -anchor w
|
|
entry $wf.e -textvariable smb_host_list -width 60
|
|
button $wf.b -text "Apply" -command {make_share_widgets .smbwiz.f.t.f3}
|
|
bind $wf.e <Return> "$wf.b invoke"
|
|
pack $wf.l $wf.e $wf.b -side left
|
|
pack $wf
|
|
pack $w
|
|
|
|
.smbwiz.f.t window create end -window $w
|
|
|
|
.smbwiz.f.t insert end "\n$id"
|
|
|
|
set w .smbwiz.f.t.f5
|
|
frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
|
|
set wf .smbwiz.f.t.f5.f
|
|
frame $wf
|
|
label $wf.l -text "Mount Prefix:" -anchor w
|
|
entry $wf.e -textvariable smb_mount_prefix -width 60
|
|
button $wf.b -text "Apply" -command {apply_mount_point_prefix .smbwiz.f.t.f5.f.e}
|
|
bind $wf.e <Return> "$wf.b invoke"
|
|
pack $wf.l $wf.e $wf.b -side left
|
|
pack $wf
|
|
pack $w
|
|
|
|
.smbwiz.f.t window create end -window $w
|
|
|
|
.smbwiz.f.t insert end "\n\n\n"
|
|
|
|
.smbwiz.f.t see 1.0
|
|
.smbwiz.f.t configure -state disabled
|
|
update
|
|
|
|
vwait smb_wiz_done
|
|
catch {destroy .smbwiz}
|
|
|
|
if {! $smbmount_exists || $smbmount_sumode == "dontknow"} {
|
|
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"
|
|
global use_smbmnt
|
|
set use_smbmnt 0
|
|
catch {raise .oa}
|
|
return
|
|
}
|
|
global smb_su_mode
|
|
set smb_su_mode $smbmount_sumode
|
|
|
|
set max 0
|
|
foreach en [array names smb_selected_en] {
|
|
set i $smb_selected_en($en)
|
|
set host $smb_selected_host($i)
|
|
set name $smb_selected_name($i)
|
|
|
|
set len [string length "//$host/$name"]
|
|
if {$len > $max} {
|
|
set max $len
|
|
}
|
|
}
|
|
|
|
set max [expr $max + 8]
|
|
|
|
set strs ""
|
|
foreach en [array names smb_selected_en] {
|
|
set i $smb_selected_en($en)
|
|
if {! $smb_selected($i)} {
|
|
continue
|
|
}
|
|
set host $smb_selected_host($i)
|
|
set name $smb_selected_name($i)
|
|
set mnt $smb_selected_mnt($i)
|
|
|
|
set share "//$host/$name"
|
|
set share [format "%-${max}s" $share]
|
|
|
|
lappend strs "$share $mnt"
|
|
}
|
|
set text ""
|
|
foreach str [lsort $strs] {
|
|
append text "$str\n"
|
|
}
|
|
|
|
global smb_mount_list
|
|
set smb_mount_list $text
|
|
|
|
smb_dialog
|
|
}
|
|
|
|
proc apply_mount_point_prefix {w} {
|
|
global smb_selected_host smb_selected_name
|
|
global smb_selected_en smb_selected_mnt
|
|
|
|
set prefix ""
|
|
catch {set prefix [$w get]}
|
|
if {$prefix == ""} {
|
|
mesg "No mount prefix."
|
|
bell
|
|
return
|
|
}
|
|
|
|
foreach en [array names smb_selected_en] {
|
|
set i $smb_selected_en($en)
|
|
set host $smb_selected_host($i)
|
|
set name $smb_selected_name($i)
|
|
set smb_selected_mnt($i) "$prefix/$host/$name"
|
|
}
|
|
}
|
|
|
|
proc smb_dialog {} {
|
|
toplev .smb
|
|
wm title .smb "SMB Filesystem Tunnelling"
|
|
global smb_su_mode smb_mount_list
|
|
global use_smbmnt
|
|
|
|
global help_font
|
|
|
|
global uname
|
|
set h 33
|
|
if [small_height] {
|
|
set h 17
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 24
|
|
}
|
|
scroll_text .smb.f 80 $h
|
|
|
|
set msg {
|
|
Windows/Samba Filesystem mounting requires SSH be used to set up the SMB
|
|
service port redirection. This will be either of the "Use SSH" or
|
|
"SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work.
|
|
|
|
This method requires a working Samba software setup on the remote
|
|
side of the connection (VNC server) and existing Samba or Windows file
|
|
server(s) on the local side (VNC viewer).
|
|
|
|
The smbmount(8) program MUST be installed on the remote side. This
|
|
evidently limits the mounting to Linux systems. Let us know of similar
|
|
utilities on other Unixes. Mounting onto remote Windows machines is
|
|
currently not supported (our SSH mode with services setup only works
|
|
to Unix). On Debian and Ubuntu the smbmount program is currently in
|
|
the package named 'smbfs'.
|
|
|
|
Depending on how smbmount is configured you may be able to run it
|
|
as a regular user, or it may require running under su(1) or sudo(8)
|
|
(root password or user password required, respectively). You select
|
|
which one you want via the checkbuttons below.
|
|
|
|
In addition to a possible su(1) or sudo(8) password, you may ALSO
|
|
need to supply passwords to mount each SMB share. This is an SMB passwd.
|
|
If it has no password just hit enter after the "Password:" prompt.
|
|
|
|
The passwords are supplied when the 1st SSH connection starts up;
|
|
be prepared to respond to them.
|
|
|
|
NOTE: USE OF SMB TUNNELLING MODE WILL REQUIRE TWO SSH'S, AND SO YOU
|
|
MAY NEED TO SUPPLY TWO LOGIN PASSWORDS UNLESS YOU ARE USING SOMETHING
|
|
LIKE ssh-agent(1) or the Putty PW setting.
|
|
%WIN
|
|
|
|
To indicate the Windows/Samba shares to mount enter them one per line
|
|
in one of the forms:
|
|
|
|
//machine1/share ~/Desktop/my-mount1
|
|
//machine2/fubar /var/tmp/my-foobar2 192.168.100.53:3456
|
|
1139 //machine3/baz /var/tmp/baz [...]
|
|
|
|
The first part is the standard SMB host and share name //hostname/dir
|
|
(note this share is on the local viewer-side not on the remote end).
|
|
A leading '#' will cause the entire line to be skipped.
|
|
|
|
The second part, e.g. /var/tmp/my-foobar2, is the directory to mount
|
|
the share on the remote (VNC Server) side. You must be able to
|
|
write to this directory. It will be created if it does not exist.
|
|
A leading character ~ will be expanded to $HOME. So will the string
|
|
%HOME. The string %USER will get expanded to the remote username.
|
|
|
|
An optional part like 192.168.100.53:3456 is used to specify the real
|
|
hostname or IP address, and possible non-standard port, on the local
|
|
side if for some reason the //hostname is not sufficient.
|
|
|
|
An optional leading numerical value, 1139 in the above example, indicates
|
|
which port to use on the Remote side to SSH redirect to the local side.
|
|
Otherwise a random one is tried (a unique one is needed for each SMB
|
|
server:port combination). A fixed one is preferred: choose a free
|
|
remote port.
|
|
|
|
The standard SMB service ports (local side) are 445 and 139. 139 is
|
|
used by this application.
|
|
|
|
Sometimes "localhost" will not work on Windows machines for a share
|
|
hostname, and you will have to specify a different network interface
|
|
(e.g. the machine's IP address). If you use the literal string "IP"
|
|
it will be attempted to replace it with the numerical IP address, e.g.:
|
|
|
|
//machine1/share ~/Desktop/my-mount1 IP
|
|
|
|
VERY IMPORTANT: Before terminating the VNC Connection, make sure no
|
|
applications are using any of the SMB shares (or shells are cd-ed
|
|
into the share). This way the shares will be automatically unmounted.
|
|
Otherwise you will need to log in again, stop processes from using
|
|
the share, become root and umount the shares manually ("smbumount
|
|
/path/to/share", etc.)
|
|
|
|
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-smb-shares
|
|
}
|
|
|
|
set msg2 {
|
|
To speed up moving to the next step, iconify the first SSH console
|
|
when you are done entering passwords, etc. and then click on the
|
|
main panel 'VNC Host:Display' label.
|
|
}
|
|
|
|
global is_windows
|
|
if {! $is_windows} {
|
|
regsub { *%WIN} $msg "" msg
|
|
} else {
|
|
set msg2 [string trim $msg2]
|
|
regsub { *%WIN} $msg " $msg2" msg
|
|
}
|
|
.smb.f.t insert end $msg
|
|
|
|
frame .smb.r
|
|
label .smb.r.l -text "smbmount(8) auth mode:" -relief ridge
|
|
radiobutton .smb.r.none -text "None" -variable smb_su_mode -value "none"
|
|
radiobutton .smb.r.su -text "su(1)" -variable smb_su_mode -value "su"
|
|
radiobutton .smb.r.sudo -text "sudo(8)" -variable smb_su_mode -value "sudo"
|
|
|
|
pack .smb.r.l .smb.r.none .smb.r.sudo .smb.r.su -side left -fill x
|
|
|
|
label .smb.info -text "Supply the mounts (one per line) below:" -anchor w -relief ridge
|
|
|
|
eval text .smb.mnts -width 80 -height 5 $help_font
|
|
.smb.mnts insert end $smb_mount_list
|
|
|
|
button .smb.guess -text "Help me decide ..." -command {destroy .smb; smb_help_me_decide}
|
|
|
|
button .smb.cancel -text "Cancel" -command {set use_smbmnt 0; destroy .smb}
|
|
bind .smb <Escape> {set use_smbmnt 0; destroy .smb}
|
|
wm protocol .smb WM_DELETE_WINDOW {set use_smbmnt 0; destroy .smb}
|
|
button .smb.done -text "Done" -command {if {$use_smbmnt} {set_ssh; set smb_mount_list [.smb.mnts get 1.0 end]}; destroy .smb}
|
|
|
|
pack .smb.done .smb.cancel .smb.guess .smb.mnts .smb.info .smb.r -side bottom -fill x
|
|
pack .smb.f -side top -fill both -expand 1
|
|
|
|
center_win .smb
|
|
}
|
|
|
|
proc help_advanced_opts {} {
|
|
toplev .ah
|
|
|
|
scroll_text_dismiss .ah.f
|
|
|
|
center_win .ah
|
|
|
|
wm title .ah "Advanced Options Help"
|
|
|
|
set msg {
|
|
These Advanced Options that may require extra software installed on
|
|
the VNC server-side (the remote server machine) and/or on the VNC
|
|
client-side (where this gui is running).
|
|
|
|
The Service redirection options, CUPS, ESD/ARTSD, and SMB will
|
|
require that you use SSH for tunneling so that they can use the -R
|
|
port redirection will be enabled for each service. I.e. "Use SSH"
|
|
or "SSH + SSL" mode.
|
|
|
|
These options may also require additional configuration to get them
|
|
to work properly. Please submit bug reports if it appears it should
|
|
be working for your setup but is not.
|
|
|
|
Brief (and some not so brief) descriptions:
|
|
|
|
CUPS Print tunnelling:
|
|
|
|
Redirect localhost:6631 (say) on the VNC server to your local
|
|
CUPS server. SSH mode is required.
|
|
|
|
ESD/ARTSD Audio tunnelling:
|
|
|
|
Redirect localhost:16001 (say) on the VNC server to your local
|
|
ESD, etc. sound server. SSH mode is required.
|
|
|
|
SMB mount tunnelling:
|
|
|
|
Redirect localhost:1139 (say) on the VNC server and through that
|
|
mount SMB file shares from your local server. The remote machine
|
|
must be Linux with smbmount installed. SSH mode is required.
|
|
|
|
Additional Port Redirs (via SSH):
|
|
|
|
Specify additional -L port:host:port and -R port:host:port
|
|
cmdline options for SSH to enable additional services.
|
|
SSH mode is required.
|
|
|
|
Automatically Find X Login/Greeter:
|
|
|
|
This mode is similar to "Automatically Find X Session" except
|
|
that it will attach to a X Login/Greeter screen that no one
|
|
has logged into yet. It requires root privileges via sudo(1)
|
|
on the remote machine. SSH mode is required.
|
|
|
|
As with "Automatically Find X Session" it works only with SSH
|
|
mode and requires x11vnc be installed on the remote computer.
|
|
|
|
It simply sets the Remote SSH Command to:
|
|
|
|
PORT= sudo x11vnc -find -localhost -env FD_XDM=1
|
|
|
|
An initial ssh running 'sudo id' is performed to try to
|
|
'prime' sudo so the 2nd one that runs x11vnc does not need
|
|
a password. This may not always succeed... please mail us
|
|
the details if it doesn't.
|
|
|
|
See the 'X Login' description in 'Terminal Services' Mode
|
|
Help for more info.
|
|
|
|
Private SSH KnownHosts file:
|
|
|
|
On Unix in SSH mode, let the user specify a non-default
|
|
ssh known_hosts file to be used only by the current profile.
|
|
This is the UserKnownHostsFile ssh option and is described in the
|
|
ssh_config(1) man page. This is useful to avoid proxy 'localhost'
|
|
SSH key collisions.
|
|
|
|
Normally one should simply let ssh use its default file
|
|
~/.ssh/known_hosts for tracking SSH keys. The only problem that
|
|
happens is when multiple SSVNC connections use localhost tunnel
|
|
port redirections. These make ssh connect to 'localhost' on some
|
|
port (where the proxy is listening.) Then the different keys
|
|
from the multiple ssh servers collide when ssh saves them under
|
|
'localhost' in ~/.ssh/known_hosts.
|
|
|
|
So if you are using a proxy with SSVNC or doing a "double SSH
|
|
gateway" your ssh will connect to a proxy port on localhost, and you
|
|
should set a private KnownHosts file for that connection profile.
|
|
This is secure and avoids man-in-the-middle attack (as long as
|
|
you actually verify the initial save of the SSH key!)
|
|
|
|
The default file location will be:
|
|
|
|
~/.vnc/ssh_known_hosts/profile-name.known
|
|
|
|
but you can choose any place you like. It must of course be
|
|
unique and not shared with another ssh connection otherwise they
|
|
both may complain about the key for 'localhost' changing, etc.
|
|
|
|
SSH Local Port Protections:
|
|
|
|
An LD_PRELOAD hack to limit the number of SSH port redirections
|
|
to 1 and within the first 35 seconds. So there is a smaller
|
|
window when the user can try to use your tunnel compared to
|
|
the duration of your session. SSH mode is required.
|
|
|
|
STUNNEL Local Port Protections:
|
|
|
|
Try to prevent Untrusted Local Users (see the main Help panel)
|
|
from using your STUNNEL tunnel to connect to the remote VNC
|
|
Server.
|
|
|
|
Change VNC Viewer:
|
|
|
|
Specify a non-bundled VNC Viewer (e.g. UltraVNC or RealVNC)
|
|
to run instead of the bundled TightVNC Viewer.
|
|
|
|
Port Knocking:
|
|
|
|
For "closed port" services, first "knock" on the firewall ports
|
|
in a certain way to open the door for SSH or SSL. The port
|
|
can also be closed when the encrypted VNC connection finishes.
|
|
|
|
UltraVNC DSM Encryption Plugin:
|
|
|
|
On Unix only, by using the supplied tool, ultravnc_dsm_helper,
|
|
encrypted connections to UltraVNC servers using their plugins
|
|
is enabled. Support for secret key encryption to Non-UltraVNC
|
|
DSM servers is also supported, e.g. x11vnc -enc blowfish:my.key
|
|
|
|
Do not Probe for VeNCrypt:
|
|
|
|
Disable VeNCrypt auto-detection probe when not needed.
|
|
|
|
By default in SSL mode an initial probe for the use of the
|
|
VeNCrypt or ANONTLS protocol is performed. This is done
|
|
during the initial fetch-cert action. Once auto-detected in
|
|
the initial probe, the real connection to the VNC Server will
|
|
use this information to switch to SSL/TLS at the right point in
|
|
the VeNCrypt/ANONTLS handshake.
|
|
|
|
In "Verify All Certs" mode initial the fetch-cert action is
|
|
required so the automatic probing for VeNCrypt is always done.
|
|
The fetch-cert is not needed if you specified a ServerCert or if
|
|
you disabled "Verify All Certs". But by default the fetch-cert
|
|
is done anyway to try to auto-detect VeNCrypt/ANONTLS.
|
|
|
|
Set 'Do not Probe for VeNCrypt' to skip this unneeded fetch-cert
|
|
action (and hence speed up connecting.) Use this if you
|
|
know the VNC Server uses normal SSL and not VeNCrypt/ANONTLS.
|
|
|
|
See also the next option, 'Server uses VeNCrypt SSL encryption'
|
|
to if you know it uses VeNCrypt/ANONTLS (the probing will also
|
|
be skipped if that option is set.)
|
|
|
|
Server uses VeNCrypt SSL encryption:
|
|
|
|
Indicate that the VNC server uses the VeNCrypt extension to VNC;
|
|
it switches to an SSL/TLS tunnel at a certain point in the
|
|
VNC Handshake. This is in constrast to the default ssvnc/x11vnc
|
|
SSL tunnel behavior where the *entire* VNC traffic goes through
|
|
SSL (i.e. it is vncs:// in the way https:// uses SSL)
|
|
|
|
Enable this option if you know the server supports VeNCrypt.
|
|
Also use this option for the older ANONTLS extension (vino).
|
|
Doing so will give the quickest and most reliable connection
|
|
to VeNCrypt/ANONTLS servers. If set, any probing to try to
|
|
auto-detect VeNCrypt/ANONTLS will be skipped.
|
|
|
|
Some VNC servers supporting VeNCrypt: VeNCrypt, QEMU, ggi,
|
|
virt-manager, and Xen. Vino supports ANONTLS.
|
|
|
|
The SSVNC VeNCrypt/ANONTLS support even works with 3rd party
|
|
VNC Viewers you specify via 'Change VNC Viewer' (e.g. RealVNC,
|
|
TightVNC, UltraVNC etc.) that do not directly support it.
|
|
|
|
Note: many VeNCrypt servers only support Anonymous Diffie Hellman
|
|
TLS which has NO built in authentication and you will also need
|
|
to set the option described in the next section.
|
|
|
|
If you are using VeNCrypt or ANONTLS for REVERSE connections
|
|
(Listen) then you *MUST* set this 'Server uses VeNCrypt SSL
|
|
encryption' option. Note also that REVERSE connections using
|
|
VeNCrypt/ANONTLS currently do not work on Windows.
|
|
|
|
Also, if you are using the "Use SSH+SSL" double tunnel to a
|
|
VeNCrypt/ANONTLS server, you MUST set 'Server uses VeNCrypt
|
|
SSL encryption' because "Verify All Certs" is disabled in
|
|
SSH+SSL mode.
|
|
|
|
Server uses Anonymous Diffie-Hellman
|
|
|
|
Anonymous Diffie-Hellman can be used for SSL/TLS connections but
|
|
there are no Certificates for authentication. Therefore only
|
|
passive eavesdropping attacks are prevented, not Man-In-The-Middle
|
|
attacks. Not recommended; try to use verified X509 certs instead.
|
|
|
|
Enable this option if you know the server only supports Anon DH.
|
|
When you do so, remember that ALL Certificate checking will be
|
|
skipped (even if you have 'Verify All Certs' selected or set
|
|
a ServerCert.)
|
|
|
|
SSVNC may be able to autodetect Anon DH even if you haven't
|
|
selected 'Server uses Anonymous Diffie-Hellman'. Once detected, it
|
|
will prompt you whether it should continue. Set the 'Server uses
|
|
Anonymous Diffie-Hellman' option to avoid trying autodetection
|
|
(i.e. forcing the issue.)
|
|
|
|
Note that most Anonymous Diffie-Hellman VNC Servers do so
|
|
via the VeNCrypt or ANONTLS VNC extensions (see the previous
|
|
section.) For these servers if you select 'Server uses Anonymous
|
|
Diffie-Hellman' you *MUST* ALSO select 'Server uses VeNCrypt SSL
|
|
encryption', otherwise SSVNC may have no chance to auto-detect
|
|
the VeNCrypt/ANONTLS protocol.
|
|
|
|
Also note, if you are using the "Use SSH+SSL" double tunnel to
|
|
a VeNCrypt/ANONTLS server using Anon DH you MUST set 'Server
|
|
uses Anonymous Diffie-Hellman' because "Verify All Certs"
|
|
is disabled in SSH+SSL mode.
|
|
|
|
Include:
|
|
|
|
Default settings and Include Templates:
|
|
|
|
Before explaining how Include works, first note that if you
|
|
do not prefer some of SSVNC's default settings you can start
|
|
up SSVNC and then change the settings for the options that you
|
|
want to have a different default value. Then type "defaults"
|
|
in VNC Host:Display entry box and press "Save" to save them in
|
|
the "defaults.vnc" profile. After this, SSVNC will initialize
|
|
all of the default values and then apply your override values
|
|
in "defaults".
|
|
|
|
For example, suppose you always want to use a different, 3rd
|
|
party VNC Viewer. Set Options -> Advanced -> Change VNC Viewer
|
|
to what you want, and then save it as the "defaults" profile.
|
|
Now that default setting will apply to all profiles, and SSVNC
|
|
in its startup state.
|
|
|
|
To edit the defaults Load it, make changes, and then Save it.
|
|
Delete the "defaults" profile to go back to no modifications.
|
|
Note that defaults created and saved while defaults.vnc existed
|
|
will NOT be automatically adjusted.
|
|
|
|
Include Templates:
|
|
|
|
Now suppose you have a certain class of settings that you do
|
|
not want to always be applied, but you want them to apply to a
|
|
group of profiles.
|
|
|
|
For example, suppose you have some settings for very low
|
|
bandwidth connections (e.g. low color modes and/or aggressive
|
|
compression and quality settings.) Set these values in SSVNC
|
|
and then in the VNC Host:Display entry box type in, say,
|
|
"slowlink" and then press Save. This will save those settings
|
|
in the template profile named "slowlink.vnc".
|
|
|
|
Now to create a real profile that uses this template type the
|
|
host:disp in "VNC Host:Display" and in Options -> Advanced
|
|
-> Includes type in "slowlink". Then press Save to save the
|
|
host profile. Then re-Load it. The "slowlink" settings will
|
|
be applied after the defaults. Make any other changes to the
|
|
setting for this profile and Save it again. Next time you load
|
|
it in, the Include template settings will override the defaults
|
|
and then the profile itself is read in.
|
|
|
|
You may supply a comma or space separated list of templates
|
|
to include. They are applied in the order listed. They can be
|
|
full path names or basenames relative to the profiles directory.
|
|
You do not need to supply the .vnc suffix. The non-default
|
|
settings in them will be applied first, and then any values in
|
|
the loaded Profile will override them.
|
|
|
|
Sleep:
|
|
|
|
Enter a number to indicate how many extra seconds to sleep
|
|
while waiting for the VNC viewer to start up. On Windows this
|
|
can give extra time to enter the Putty/Plink password, etc.
|
|
|
|
Putty Args:
|
|
|
|
Windows only, supply a string to be added to all plink.exe
|
|
and putty.exe commands. Example: -i C:\mykey.ppk
|
|
|
|
Launch Putty Pagent:
|
|
|
|
Windows only, launch the Putty key agent tool (pageant) to hold
|
|
your SSH private keys for automatic logging in by putty/plink.
|
|
|
|
Launch Putty Key-Gen:
|
|
|
|
Windows only, launch the Putty key generation tool (puttygen)
|
|
to create new SSH private keys.
|
|
|
|
Unix ssvncviewer:
|
|
|
|
Display a popup menu with options that apply to the special
|
|
Unix SSVNC VNC Viewer (perhaps called 'ssvncviewer') provided by
|
|
this SSVNC package. This only applies to Unix or Mac OS X.
|
|
|
|
Use ssh-agent:
|
|
|
|
On Unix only: restart the GUI in the presence of ssh-agent(1)
|
|
(e.g. in case you forgot to start your agent before starting
|
|
this GUI). An xterm will be used to enter passphrases, etc.
|
|
This can avoid repeatedly entering passphrases for the SSH logins
|
|
(note this requires setting up and distributing SSH keys).
|
|
|
|
|
|
About the CheckButtons:
|
|
|
|
Ahem, Well...., yes quite a klunky UI: you have to toggle the
|
|
CheckButton to pull up the Dialog box a 2nd, etc. time... don't
|
|
worry your settings will still be there!
|
|
}
|
|
|
|
.ah.f.t insert end $msg
|
|
jiggle_text .ah.f.t
|
|
}
|
|
|
|
proc help_ssvncviewer_opts {} {
|
|
toplev .av
|
|
|
|
scroll_text_dismiss .av.f
|
|
|
|
center_win .av
|
|
|
|
wm title .av "Unix SSVNC viewer Options Help"
|
|
|
|
set msg {
|
|
These Unix SSVNC VNC Viewer Options apply only on Unix or Mac OS X
|
|
when using the viewer (ssvncviewer) supplied by this SSVNC package.
|
|
|
|
Brief descriptions:
|
|
|
|
Multiple LISTEN Connections:
|
|
|
|
Allow multiple VNC servers to reverse connect at the same time
|
|
and so display each of their desktops on your screen at the
|
|
same time.
|
|
|
|
Listen Once:
|
|
|
|
Try to have the VNC Viewer exit after the first listening
|
|
connection. (It may not always be detected; use Ctrl-C to exit)
|
|
|
|
Listen Accept Popup Dialog:
|
|
|
|
In -listen (reverse connection listening) mode when a reverse
|
|
VNC connection comes in show a popup asking whether to Accept
|
|
or Reject the connection. (-acceptpopup vncviewer option.)
|
|
|
|
Accept Popup UltraVNC Single Click:
|
|
|
|
As in 'Listen Accept Popup Dialog', except assume the remote
|
|
VNC server is UltraVNC Single Click and force the execution of
|
|
the protocol to retrieve the extra remote-side info (Windows
|
|
User, ComputerName, etc) which is then also displayed in the
|
|
Popup window. (-acceptpopupsc vncviewer option.)
|
|
|
|
Use X11 Cursor:
|
|
|
|
When drawing the mouse cursor shape locally, use an X11 cursor
|
|
instead of drawing it directly into the framebuffer. This
|
|
can sometimes give better response, and avoid problems under
|
|
'Scaling'.
|
|
|
|
Disable Bell:
|
|
|
|
Disable beeps coming from remote side.
|
|
|
|
Use Raw Local:
|
|
|
|
Use the VNC Raw encoding for 'localhost' connections (instead
|
|
of assuming there is a local tunnel, SSL or SSH, going to the
|
|
remote machine.
|
|
|
|
Avoid Using Terminal:
|
|
|
|
By default the Unix ssvncviewer will prompt for usernames,
|
|
passwords, etc. in the terminal it is running inside of.
|
|
Set this option to use windows for messages and prompting as
|
|
much as possible. Messages will also go to the terminal, but
|
|
all prompts will be done via popup window.
|
|
|
|
Note that stunnel(1) may prompt for a passphrase to unlock a
|
|
private SSL key. This is fairly rare because it is usually
|
|
for Client-side SSL authentication. stunnel will prompt from
|
|
the terminal; there seems to be no way around this.
|
|
|
|
Also, note that ssh(1) may prompt for an ssh key passphrase
|
|
or Unix password. This can be avoided in a number of ways,
|
|
the simplest one is to use ssh-agent(1) and ssh-add(1).
|
|
However ssh(1) may also prompt you to accept a new public key
|
|
for a host or warn you if the key has changed, etc.
|
|
|
|
Use Popup Fix:
|
|
|
|
Enable a fix that warps the popup (F8) to the mouse pointer.
|
|
|
|
Use XGrabServer (for fullscreen):
|
|
|
|
On Unix only, use the XGrabServer workaround for older window
|
|
managers. Sometimes also needed on recent (2008) GNOME. This
|
|
workaround can make going into/out-of Fullscreen work better.
|
|
|
|
Cursor Alphablending:
|
|
|
|
Use the x11vnc alpha hack for translucent cursors (requires Unix,
|
|
32bpp and same endianness)
|
|
|
|
TurboVNC:
|
|
|
|
If available on your platform, use a ssvncviewer compiled with
|
|
TurboVNC support. This is based on the VirtualGL project:
|
|
http://www.sourceforge.net/projects/virtualgl You will need
|
|
to install the VirtualGL's TurboJPEG library too.
|
|
|
|
Currently (May/2009) only Linux.i686, Linux.x86_64, and
|
|
Darwin.i386 have vncviewer.turbovnc binaries shipped in the
|
|
ssvnc bundles. See the build instructions for how you might
|
|
compile your own.
|
|
|
|
Disable Pipelined Updates:
|
|
|
|
Disable the TurboVNC-like pipelined updates mode. Pipelined
|
|
updates is the default even when not TurboVNC enabled. They
|
|
ask for the next screen update before the current one has
|
|
finished downloading, and so this might reduce the slowdown
|
|
due to high latency or low bandwidth by 2X or so. Disable
|
|
them if they cause problems with the remote VNC Server or
|
|
use too much bandwidth.
|
|
|
|
Send CLIPBOARD not PRIMARY:
|
|
|
|
When sending locally selected text to the VNC server side,
|
|
send the CLIPBOARD selection instead of the PRIMARY selection.
|
|
|
|
Send Selection Every time:
|
|
|
|
Send selected text to the VNC server side every time the mouse
|
|
focus enters the main VNC Viewer window instead only when it
|
|
appears to have changed since the last send.
|
|
|
|
Scaling:
|
|
|
|
Use viewer-side (i.e. local) scaling of the VNC screen. Supply
|
|
a fraction, e.g. 0.75 or 3/4, or a WxH geometry, e.g. 1280x1024,
|
|
or the string 'fit' to fill the current screen. Use 'auto'
|
|
to scale the desktop to match the viewer window size.
|
|
|
|
If you observe mouse trail painting errors try using X11 Cursor.
|
|
|
|
Note that since the local scaling is done in software it can
|
|
be slow. Since ZRLE is better than Tight in this regard, when
|
|
scaling is detected, the encoding will be switched to ZRLE.
|
|
Use the Popup to go back to Tight if you want to, or set the
|
|
env. var. SSVNC_PRESERVE_ENCODING=1 to disable the switch.
|
|
|
|
For additional speedups under local scaling: try having a solid
|
|
desktop background on the remote side (either manually or using
|
|
'x11vnc -solid ...'); and also consider using client side caching
|
|
'x11vnc -ncache 10 ...' if the remote server is x11vnc.
|
|
|
|
Escape Keys:
|
|
|
|
Enable 'Escape Keys', a set of modifier keys that, if all are
|
|
pressed down, enable local Hot Key actions. Set to 'default'
|
|
to use the default (Alt_L,Super_L on unix, Control_L,Meta_L
|
|
on macosx) or set to a list of modifier keys.
|
|
|
|
Y Crop:
|
|
|
|
This is for x11vnc's -ncache client side caching scheme with our
|
|
Unix TightVNC viewer. Sets the Y value to "crop" the viewer
|
|
size at (below the cut is the pixel cache region you do not
|
|
want to see). If the screen is tall (H > 2*W) ycropping will
|
|
be autodetected, or you can set to -1 to force autodection.
|
|
Otherwise, set it to the desired Y value. You can also set
|
|
the scrollbar width (very thin by default) by appending ",sb=N"
|
|
(or use ",sb=N" by itself to just set the scrollbar width).
|
|
|
|
ScrollBar Width:
|
|
|
|
This is for x11vnc's -ncache client side caching scheme with our
|
|
Unix TightVNC viewer. For Y-Crop mode, set the size of the
|
|
scrollbars (often one want it to be very narrow, e.g. 2 pixels
|
|
to be less distracting.
|
|
|
|
RFB Version:
|
|
|
|
Set the numerical version of RFB (VNC) protocol to pretend to
|
|
be, 3.x. Usually only needed with UltraVNC servers.
|
|
|
|
Encodings:
|
|
|
|
List encodings in preferred order, for example
|
|
'copyrect zrle tight' The list of encodings is:
|
|
copyrect tight zrle zywrle hextile zlib corre rre raw
|
|
|
|
Extra Options:
|
|
|
|
String of extra Unix ssvncviewer command line options. I.e. for
|
|
ones like -16bpp that cannot be set inside this SSVNC GUI. For a
|
|
list click Help then 'SSVNC vncviewer -help Output'.
|
|
|
|
|
|
These are environment variables one may set to affect the options
|
|
of the SSVNC vncviewer and also the ss_vncviewer wrapper script
|
|
(and hence may apply to 3rd party vncviewers too)
|
|
|
|
VNCVIEWER_ALPHABLEND (-alpha, see Cursor Alphablending above)
|
|
VNCVIEWER_POPUP_FIX (-popupfix, warp popup to mouse location)
|
|
VNCVIEWER_GRAB_SERVER (-graball, see Use XGrabServer above)
|
|
VNCVIEWER_YCROP (-ycrop, see Y Crop above)
|
|
VNCVIEWER_SBWIDTH (-sbwidth, see ScrollBar Width above)
|
|
VNCVIEWER_RFBVERSION (-rfbversion, e.g. 3.6)
|
|
VNCVIEWER_ENCODINGS (-encodings, e.g. "copyrect zrle hextile")
|
|
VNCVIEWER_NOBELL (-nobell)
|
|
VNCVIEWER_X11CURSOR (-x11cursor, see Use X11 Cursor above)
|
|
VNCVIEWER_RAWLOCAL (-rawlocal, see Use Raw Local above)
|
|
VNCVIEWER_NOTTY (-notty, see Avoid Using Terminal above)
|
|
VNCVIEWER_ESCAPE (-escape, see Escape Keys above)
|
|
VNCVIEWER_ULTRADSM (-ultradsm)
|
|
VNCVIEWER_PIPELINE_UPDATES (-pipeline, see above)
|
|
VNCVIEWER_SEND_CLIPBOARD (-sendclipboard)
|
|
VNCVIEWER_SEND_ALWAYS (-sendalways)
|
|
VNCVIEWER_RECV_TEXT (-recvtext clipboard/primary/both)
|
|
VNCVIEWER_NO_CUTBUFFER (do not send CUTBUFFER0 as fallback)
|
|
VNCVIEWER_NO_PIPELINE_UPDATES (-nopipeline)
|
|
VNCVIEWER_ALWAYS_RECENTER (set to avoid(?) recentering on resize)
|
|
VNCVIEWER_IS_REALVNC4 (indicate vncviewer is realvnc4 flavor.)
|
|
VNCVIEWER_NO_IPV4 (-noipv4)
|
|
VNCVIEWER_NO_IPV6 (-noipv6)
|
|
VNCVIEWER_FORCE_UP (force raise on fullscreen graball)
|
|
VNCVIEWER_PASSWORD (danger: set vnc passwd via env. var.)
|
|
VNCVIEWER_MIN_TITLE (minimum window title (appshare))
|
|
|
|
VNCVIEWERCMD (unix viewer command, default vncviewer)
|
|
VNCVIEWERCMD_OVERRIDE (force override of VNCVIEWERCMD)
|
|
VNCVIEWERCMD_EXTRA_OPTS (extra options to pass to VNCVIEWERCMD)
|
|
VNCVIEWER_LISTEN_LOCALHOST (force ssvncviewer to -listen on localhost)
|
|
VNCVIEWER_NO_SEC_TYPE_TIGHT(force ssvncviewer to skip rfbSecTypeTight)
|
|
HEXTILE_YCROP_TOO (testing: nosync_ycrop for hextile updates.)
|
|
|
|
SS_DEBUG (very verbose debug printout by script.)
|
|
SS_VNCVIEWER_LISTEN_PORT (force listen port.)
|
|
SS_VNCVIEWER_NO_F (no -f for SSH.)
|
|
SS_VNCVIEWER_NO_T (no -t for SSH.)
|
|
SS_VNCVIEWER_USE_C (force -C compression for SSH.)
|
|
SS_VNCVIEWER_SSH_CMD (override SSH command to run.)
|
|
SS_VNCVIEWER_NO_MAXCONN (no maxconn for stunnel (obsolete))
|
|
SS_VNCVIEWER_RM (file containing vnc passwd to remove.)
|
|
SS_VNCVIEWER_SSH_ONLY (run the SSH command, then exit.)
|
|
|
|
SSVNC_MULTIPLE_LISTEN (-multilisten, see Multiple LISTEN above)
|
|
SSVNC_ACCEPT_POPUP (-acceptpopup, see Accept Popup Dialog)
|
|
SSVNC_ACCEPT_POPUP_SC (-acceptpopupsc, see Accept Popup Dialog)
|
|
SSVNC_TURBOVNC (see TurboVNC above)
|
|
SSVNC_UNIXPW (-unixpw)
|
|
SSVNC_UNIXPW_NOESC (do not send escape in -unixpw mode)
|
|
SSVNC_SCALE (-scale, see Scaling above)
|
|
SSVNC_NOSOLID (do not do solid region speedup in
|
|
scaling mode.)
|
|
SSVNC_PRESERVE_ENCODING (do not switch to ZRLE when scaling)
|
|
SSVNC_FINISH_SLEEP (on unix/macosx sleep this many seconds
|
|
before exiting the terminal, default 5)
|
|
|
|
Misc (special usage or debugging or ss_vncviewer settings):
|
|
|
|
SSVNC_MESG_DELAY (sleep this many millisec between messages)
|
|
SSVNC_NO_ENC_WARN (do not print out a NO ENCRYPTION warning)
|
|
SSVNC_EXTRA_SLEEP (same as Sleep: window)
|
|
SSVNC_NO_ULTRA_DSM (disable ultravnc dsm encryption)
|
|
SSVNC_ULTRA_DSM (the ultravnc_dsm_helper command)
|
|
SSVNC_ULTRA_FTP_JAR (file location of ultraftp.jar jar file)
|
|
SSVNC_KNOWN_HOSTS_FILE (file for per-connection ssh known hosts)
|
|
SSVNC_SCALE_STATS (print scaling stats)
|
|
SSVNC_NOSOLID (disable solid special case while scaling)
|
|
SSVNC_DEBUG_RELEASE (debug printout for keyboard modifiers.)
|
|
SSVNC_DEBUG_ESCAPE_KEYS (debug printout for escape keys)
|
|
SSVNC_NO_MAYBE_SYNC (skip XSync() calls in certain painting)
|
|
SSVNC_MAX_LISTEN (number of time to listen for reverse conn.)
|
|
SSVNC_LISTEN_ONCE (listen for reverse conn. only once)
|
|
STUNNEL_LISTEN (stunnel interface for reverse conn.
|
|
SSVNC_NO_MESSAGE_POPUP (do not place info messages in popup.)
|
|
SSVNC_SET_SECURITY_TYPE (force VeNCrypt security type)
|
|
SSVNC_PREDIGESTED_HANDSHAKE (string used for VeNCrypt, etc. connect)
|
|
SSVNC_SKIP_RFB_PROTOCOL_VERSION (force viewer to be RFB 3.8)
|
|
SSVNC_DEBUG_SEC_TYPES (debug security types for VeNCrypt)
|
|
SSVNC_DEBUG_MSLOGON (extra printout for ultravnc mslogon proto)
|
|
SSVNC_DEBUG_RECTS (printout debug for RFB rectangles.)
|
|
SSVNC_DEBUG_CHAT (printout debug info for chat mode.)
|
|
SSVNC_DELAY_SYNC (faster local drawing delaying XSync)
|
|
SSVNC_DEBUG_SELECTION (printout debug for selection/clipboard)
|
|
SSVNC_REPEATER (URL-ish sslrepeater:// thing for UltraVNC)
|
|
SSVNC_VENCRYPT_DEBUG (debug printout for VeNCrypt mode.)
|
|
SSVNC_VENCRYPT_USERPASS (force VeNCrypt user:pass)
|
|
SSVNC_STUNNEL_DEBUG (increase stunnel debugging printout)
|
|
SSVNC_STUNNEL_VERIFY3 (increase stunnel verify from 2 to 3)
|
|
SSVNC_LIM_ACCEPT_PRELOAD (preload library to limit accept(2))
|
|
SSVNC_SOCKS5 (socks5 for x11vnc PORT= mode, default)
|
|
SSVNC_SOCKS4 (socks4 for x11vnc PORT= mode)
|
|
SSVNC_NO_IPV6_PROXY (do not setup a ipv6:// proxy)
|
|
SSVNC_NO_IPV6_PROXY_DIRECT (do not setup a ipv6:// proxy unencrypted)
|
|
SSVNC_PORT_IPV6 (x11vnc PORT= mode is to ipv6-only)
|
|
SSVNC_IPV6 (0 to disable ss_vncviewer ipv6 check)
|
|
SSVNC_FETCH_TIMEOUT (ss_vncviewer cert fetch timeout)
|
|
SSVNC_USE_S_CLIENT (force cert fetch to be 'openssl s_client')
|
|
SSVNC_SHOWCERT_EXIT_0 (force showcert to exit with success)
|
|
SSVNC_SSH_LOCALHOST_AUTH (force SSH localhost auth check.)
|
|
SSVNC_TEST_SEC_TYPE (force PPROXY VeNCrypt type; testing)
|
|
SSVNC_TEST_SEC_SUBTYPE (force PPROXY VeNCrypt subtype; testing)
|
|
SSVNC_EXIT_DEBUG (testing: prompt to exit at end.)
|
|
SSVNC_UP_DEBUG (gui user/passwd debug mode.)
|
|
SSVNC_UP_FILE (gui user/passwd file.)
|
|
|
|
STUNNEL_EXTRA_OPTS (extra options for stunnel.)
|
|
|
|
X11VNC_APPSHARE_DEBUG (for debugging -appshare mode.)
|
|
NO_X11VNC_APPSHARE (shift down for escape keys.)
|
|
DEBUG_HandleFileXfer (ultravnc filexfer)
|
|
DEBUG_RFB_SMSG (RFB server message debug.)
|
|
}
|
|
|
|
.av.f.t insert end $msg
|
|
button .av.htext -text "SSVNC vncviewer -help Output" -command show_viewer_help
|
|
pack .av.htext -side bottom -fill x
|
|
jiggle_text .av.f.t
|
|
}
|
|
|
|
proc show_viewer_help {} {
|
|
toplev .vhlp
|
|
|
|
set h 35
|
|
if [small_height] {
|
|
set h 30
|
|
}
|
|
scroll_text_dismiss .vhlp.f 83 $h
|
|
|
|
center_win .vhlp
|
|
wm resizable .vhlp 1 0
|
|
|
|
wm title .vhlp "SSVNC vncviewer -help Output"
|
|
|
|
set msg "-- No Help Output --"
|
|
catch {set msg [exec ss_vncviewer -viewerhelp 2>/dev/null]}
|
|
|
|
.vhlp.f.t insert end $msg
|
|
jiggle_text .vhlp.f.t
|
|
}
|
|
|
|
proc set_viewer_path {} {
|
|
global change_vncviewer_path
|
|
unix_dialog_resize .chviewer
|
|
set change_vncviewer_path [tk_getOpenFile -parent .chviewer]
|
|
catch {raise .chviewer}
|
|
update
|
|
}
|
|
|
|
proc change_vncviewer_dialog {} {
|
|
global change_vncviewer change_vncviewer_path vncviewer_realvnc4
|
|
global ts_only
|
|
|
|
toplev .chviewer
|
|
wm title .chviewer "Change VNC Viewer"
|
|
|
|
global help_font
|
|
if {$ts_only} {
|
|
eval text .chviewer.t -width 90 -height 16 $help_font
|
|
} else {
|
|
eval text .chviewer.t -width 90 -height 27 $help_font
|
|
}
|
|
apply_bg .chviewer.t
|
|
|
|
set msg {
|
|
To use your own VNC Viewer (i.e. one installed by you, not included in this
|
|
package), e.g. UltraVNC or RealVNC, type in the program name, or browse for
|
|
the full path to it. You can put command line arguments after the program.
|
|
|
|
Note that due to incompatibilities with respect to command line options
|
|
there may be issues, especially if many command line options are supplied.
|
|
You can specify your own command line options below if you like (and try to
|
|
avoid setting any others in this GUI under "Options").
|
|
|
|
If the path to the program name has spaces it in, surround it with double quotes:
|
|
|
|
"C:\Program Files\My Vnc Viewer\VNCVIEWER.EXE"
|
|
|
|
Make sure the very first character is a quote. You should quote the command
|
|
even if it is only the command line arguments that need extra protection:
|
|
|
|
"wine" -- "/home/fred/Program Flies/UltraVNC-1.0.2.exe" /64colors
|
|
|
|
Since the command line options differ between them greatly, if you know it
|
|
is of the RealVNC 4.x flavor, indicate on the check box. Otherwise we guess.
|
|
|
|
To have SSVNC act as a general STUNNEL redirector (no VNC) set the viewer to be
|
|
"xmessage OK" or "xmessage <port>" or "sleep n" or "sleep n <port>" (or "NOTEPAD"
|
|
on Windows). The default listen port is 5930. The destination is set in "VNC
|
|
Host:Display" (for a remote port less than 200 use the negative of the port value).
|
|
}
|
|
|
|
if {$ts_only} {
|
|
regsub {Note that due(.|\n)*If the} $msg "If the" msg
|
|
regsub {To have SSVNC act(.|\n)*} $msg "" msg
|
|
}
|
|
.chviewer.t insert end $msg
|
|
|
|
frame .chviewer.path
|
|
label .chviewer.path.l -text "VNC Viewer:"
|
|
entry .chviewer.path.e -width 40 -textvariable change_vncviewer_path
|
|
button .chviewer.path.b -text "Browse..." -command set_viewer_path
|
|
checkbutton .chviewer.path.r -anchor w -variable vncviewer_realvnc4 -text \
|
|
"RealVNC 4.x"
|
|
|
|
pack .chviewer.path.l -side left
|
|
pack .chviewer.path.e -side left -expand 1 -fill x
|
|
pack .chviewer.path.b -side left
|
|
pack .chviewer.path.r -side left
|
|
|
|
button .chviewer.cancel -text "Cancel" -command {destroy .chviewer; set change_vncviewer 0}
|
|
bind .chviewer <Escape> {destroy .chviewer; set change_vncviewer 0}
|
|
wm protocol .chviewer WM_DELETE_WINDOW {destroy .chviewer; set change_vncviewer 0}
|
|
button .chviewer.done -text "Done" -command {destroy .chviewer; catch {raise .oa}}
|
|
bind .chviewer.path.e <Return> {destroy .chviewer; catch {raise .oa}}
|
|
|
|
pack .chviewer.t .chviewer.path .chviewer.cancel .chviewer.done -side top -fill x
|
|
|
|
center_win .chviewer
|
|
wm resizable .chviewer 1 0
|
|
|
|
focus .chviewer.path.e
|
|
}
|
|
|
|
proc port_redir_dialog {} {
|
|
global additional_port_redirs additional_port_redirs_list
|
|
|
|
toplev .redirs
|
|
wm title .redirs "Additional Port Redirections (via SSH)"
|
|
|
|
global help_font uname
|
|
set h 35
|
|
if [small_height] {
|
|
set h 27
|
|
}
|
|
eval text .redirs.t -width 80 -height $h $help_font
|
|
apply_bg .redirs.t
|
|
|
|
set msg {
|
|
Specify any additional SSH port redirections you desire for the
|
|
connection. Put as many as you want separated by spaces. These only
|
|
apply to SSH and SSH+SSL connections, they do not apply to Pure SSL
|
|
connections.
|
|
|
|
-L port1:host:port2 will listen on port1 on the local machine (where
|
|
you are sitting) and redirect them to port2 on
|
|
"host". "host" is relative to the remote side
|
|
(VNC Server). Use "localhost" for the remote
|
|
machine itself.
|
|
|
|
-R port1:host:port2 will listen on port1 on the remote machine
|
|
(where the VNC server is running) and redirect
|
|
them to port2 on "host". "host" is relative
|
|
to the local side (where you are sitting).
|
|
Use "localhost" for this machine.
|
|
|
|
Perhaps you want a redir to a web server inside an intranet:
|
|
|
|
-L 8001:web-int:80
|
|
|
|
Or to redir a remote port to your local SSH daemon:
|
|
|
|
-R 5022:localhost:22
|
|
|
|
etc. There are many interesting possibilities.
|
|
|
|
Sometimes, especially for Windows Shares, you cannot do a -R redir to
|
|
localhost, but need to supply the IP address of the network interface
|
|
(e.g. by default the Shares do not listen on localhost:139). As a
|
|
convenience you can do something like -R 1139:IP:139 (for any port
|
|
numbers) and the IP will be attempted to be expanded. If this fails
|
|
for some reason you will have to use the actual numerical IP address.
|
|
}
|
|
.redirs.t insert end $msg
|
|
|
|
frame .redirs.path
|
|
label .redirs.path.l -text "Port Redirs:"
|
|
entry .redirs.path.e -width 40 -textvariable additional_port_redirs_list
|
|
|
|
pack .redirs.path.l -side left
|
|
pack .redirs.path.e -side left -expand 1 -fill x
|
|
|
|
button .redirs.cancel -text "Cancel" -command {set additional_port_redirs 0; destroy .redirs}
|
|
bind .redirs <Escape> {set additional_port_redirs 0; destroy .redirs}
|
|
wm protocol .redirs WM_DELETE_WINDOW {set additional_port_redirs 0; destroy .redirs}
|
|
button .redirs.done -text "Done" -command {destroy .redirs}
|
|
|
|
pack .redirs.t .redirs.path .redirs.cancel .redirs.done -side top -fill x
|
|
|
|
center_win .redirs
|
|
wm resizable .redirs 1 0
|
|
|
|
focus .redirs.path.e
|
|
}
|
|
|
|
proc stunnel_sec_dialog {} {
|
|
global stunnel_local_protection
|
|
|
|
toplev .stlsec
|
|
wm title .stlsec "STUNNEL Local Port Protections"
|
|
|
|
global help_font uname
|
|
|
|
set h 37
|
|
if [small_height] {
|
|
set h 26
|
|
}
|
|
scroll_text .stlsec.f 82 $h
|
|
|
|
apply_bg .stlsec.f
|
|
|
|
set msg {
|
|
See the discussion of "Untrusted Local Users" in the main 'Help'
|
|
panel for info about users who are able to log into the workstation
|
|
you run SSVNC on and might try to use your encrypted tunnel to gain
|
|
access to the remote VNC machine.
|
|
|
|
On Unix, for STUNNEL SSL tunnels we provide two options as extra
|
|
safeguards against untrusted local users. Both only apply to Unix/MacOSX.
|
|
Note that Both options are *IGNORED* in reverse connection (Listen) mode.
|
|
|
|
1) The first one 'Use stunnel EXEC mode' (it is mutually exclusive with
|
|
option 2). For this case the modified SSVNC Unix viewer must be
|
|
used: it execs the stunnel program instead of connecting to it via
|
|
TCP/IP. Thus there is no localhost listening port involved at all.
|
|
|
|
This is the best solution for SSL stunnel tunnels, it works well and
|
|
is currently enabled by default. Disable it if there are problems.
|
|
|
|
2) The second one 'Use stunnel IDENT check', uses the stunnel(8)
|
|
'ident = username' to use the local identd daemon (IDENT RFC 1413
|
|
http://www.ietf.org/rfc/rfc1413.txt) to check that the locally
|
|
connecting program (the SSVNC vncviewer) is being run by your userid.
|
|
See the stunnel(8) man page for details.
|
|
|
|
Normally the IDENT check service cannot be trusted much when used
|
|
*remotely* (the remote host may be have installed a modified daemon).
|
|
However when using the IDENT check service *locally* it should be
|
|
reliable. If not, it means the local machine (where you run SSVNC)
|
|
has already been root compromised and you have a serious problem.
|
|
|
|
Enabling 'Use stunnel IDENT check' requires a working identd on the
|
|
local machine. Often it is not installed or enabled (because it is not
|
|
deemed to be useful, etc). identd is usually run out of the inetd(8)
|
|
super-server. Even when installed and running it is often configured
|
|
incorrectly. On a Debian/lenny system we actually found that the
|
|
kernel module 'tcp_diag' needed to be loaded! ('modprobe tcp_diag')
|
|
}
|
|
.stlsec.f.t insert end $msg
|
|
|
|
radiobutton .stlsec.ident -relief ridge -anchor w -variable stunnel_local_protection_type -value "ident" -text "Use stunnel IDENT check"
|
|
radiobutton .stlsec.exec -relief ridge -anchor w -variable stunnel_local_protection_type -value "exec" -text "Use stunnel EXEC mode"
|
|
|
|
button .stlsec.cancel -text "Cancel" -command {set stunnel_local_protection 0; destroy .stlsec}
|
|
bind .stlsec <Escape> {set stunnel_local_protection 0; destroy .stlsec}
|
|
wm protocol .stlsec WM_DELETE_WINDOW {set stunnel_local_protection 0; destroy .stlsec}
|
|
button .stlsec.done -text "Done" -command {if {$stunnel_local_protection_type == "none"} {set stunnel_local_protection 0}; destroy .stlsec}
|
|
|
|
pack .stlsec.f .stlsec.exec .stlsec.ident .stlsec.cancel .stlsec.done -side top -fill x
|
|
|
|
center_win .stlsec
|
|
wm resizable .stlsec 1 0
|
|
}
|
|
|
|
proc disable_ssl_workarounds_dialog {} {
|
|
global disable_ssl_workarounds disable_ssl_workarounds_type
|
|
|
|
toplev .sslwrk
|
|
wm title .sslwrk "Disable SSL Workarounds"
|
|
|
|
global help_font uname
|
|
set h 36
|
|
if [small_height] {
|
|
set h 24
|
|
}
|
|
scroll_text .sslwrk.f 86 $h
|
|
|
|
apply_bg .sslwrk.f
|
|
|
|
set msg {
|
|
Some SSL implementations are incomplete or buggy or do not work properly
|
|
with other implementations. SSVNC uses STUNNEL for its SSL encryption,
|
|
and STUNNEL uses the OpenSSL SSL implementation.
|
|
|
|
This causes some problems with non-OpenSSL implementations on the VNC server
|
|
side. The most noticable one is the UltraVNC Single Click III (SSL) server:
|
|
|
|
http://www.uvnc.com/pchelpware/SCIII/index.html
|
|
|
|
It can make a reverse connection to SSVNC via an encrypted SSL tunnel.
|
|
|
|
Unfortunately, in the default operation with STUNNEL the connection will be
|
|
dropped after 2-15 minutes due to an unexpected packet.
|
|
|
|
Because of this, by default SSVNC will enable some SSL workarounds to make
|
|
connections like these work. This is the STUNNEL 'options = ALL' setting:
|
|
it enables a basic set of SSL workarounds.
|
|
|
|
You can read all about these workarounds in the stunnel(8) manpage and the
|
|
OpenSSL SSL_CTX_set_options(3) manpage.
|
|
|
|
Why are we mentioning this? STUNNELS's 'options = ALL' lowers the SSL
|
|
security a little bit. If you know you do not have an incompatible SSL
|
|
implementation on the server side (e.g. any one using OpenSSL is compatible,
|
|
x11vnc in particular), then you can regain that little bit of security by
|
|
selecting the "Disable SSL Workarounds" option.
|
|
|
|
"Disable All SSL Workarounds" selected below will do that. On the other hand,
|
|
choose "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround" to retain that one,
|
|
commonly needed workaround.
|
|
|
|
BTW, you can set the environment variable STUNNEL_EXTRA_OPTS_USER to add
|
|
any lines to the STUNNEL global config that you want to. See the stunnel(8)
|
|
man page for more details.
|
|
}
|
|
.sslwrk.f.t insert end $msg
|
|
|
|
radiobutton .sslwrk.none -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "none" -text "Disable All Workarounds"
|
|
radiobutton .sslwrk.noempty -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "noempty" -text "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround"
|
|
|
|
button .sslwrk.cancel -text "Cancel" -command {set disable_ssl_workarounds 0; destroy .sslwrk}
|
|
bind .sslwrk <Escape> {set disable_ssl_workarounds 0; destroy .sslwrk}
|
|
wm protocol .sslwrk WM_DELETE_WINDOW {set disable_ssl_workarounds 0; destroy .sslwrk}
|
|
button .sslwrk.done -text "Done" -command {destroy .sslwrk}
|
|
|
|
pack .sslwrk.f .sslwrk.none .sslwrk.noempty .sslwrk.cancel .sslwrk.done -side top -fill x
|
|
|
|
center_win .sslwrk
|
|
wm resizable .sslwrk 1 0
|
|
}
|
|
|
|
proc update_no_ultra_dsm {} {
|
|
global ultra_dsm_noultra
|
|
global ultra_dsm_type
|
|
|
|
foreach b {bf des3 aes aes256 l e} {
|
|
if {! $ultra_dsm_noultra} {
|
|
.ultradsm.nou.$b configure -state disabled
|
|
} else {
|
|
.ultradsm.nou.$b configure -state normal
|
|
}
|
|
}
|
|
if {! $ultra_dsm_noultra} {
|
|
if {$ultra_dsm_type == "arc4"} {
|
|
;
|
|
} elseif {$ultra_dsm_type == "aesv2"} {
|
|
;
|
|
} elseif {$ultra_dsm_type == "msrc4"} {
|
|
;
|
|
} elseif {$ultra_dsm_type == "msrc4_sc"} {
|
|
;
|
|
} elseif {$ultra_dsm_type == "securevnc"} {
|
|
;
|
|
} else {
|
|
set ultra_dsm_type guess
|
|
}
|
|
catch {.ultradsm.key.securevnc configure -state normal}
|
|
catch {.ultradsm.key.msrc4_sc configure -state normal}
|
|
} else {
|
|
catch {.ultradsm.key.securevnc configure -state disabled}
|
|
catch {.ultradsm.key.msrc4_sc configure -state disabled}
|
|
}
|
|
}
|
|
|
|
proc ultra_dsm_dialog {} {
|
|
global ultra_dsm ultra_dsm_file ultra_dsm_type
|
|
|
|
toplev .ultradsm
|
|
wm title .ultradsm "UltraVNC DSM Encryption Plugin"
|
|
|
|
global help_font
|
|
set h 40
|
|
if [small_height] {
|
|
set h 22
|
|
}
|
|
scroll_text .ultradsm.f 85 $h
|
|
|
|
set msg {
|
|
On Unix and MacOSX with the provided SSVNC vncviewer, you can connect to an
|
|
UltraVNC server that is using one of its DSM encryption plugins: MSRC4, ARC4,
|
|
AESV2, and SecureVNC. More info at: http://www.uvnc.com/features/encryption.html
|
|
|
|
IMPORTANT: The UltraVNC DSM MSRC4, ARC4, and AESV2 implementations contain
|
|
unfixed errors that could allow an eavesdropper to recover the session
|
|
key or traffic easily. They often do not provide strong encryption, but
|
|
only provide basic obscurity instead. Do not use them with critical data.
|
|
The newer SecureVNC Plugin does not suffer from these problems.
|
|
|
|
See the bottom of this help text for how to use symmetric encryption with
|
|
Non-UltraVNC servers (for example, x11vnc 0.9.5 or later). This mode does not
|
|
suffer the shortcomings of the UltraVNC MSRC4, ARC4, and AESV2 implementations.
|
|
|
|
You will need to specify the corresponding UltraVNC encryption key (created
|
|
by you using an UltraVNC server or viewer). It is usually called 'rc4.key'
|
|
(for MSRC4), 'arc4.key' (for ARC4), and 'aesv2.key' (for AESV2). Specify the
|
|
path to it or Browse for it. Also, specify which type of plugin it is (or use
|
|
'guess' to have it guess via the before mentioned filenames).
|
|
|
|
The choice "UVNC SC" enables a special workaround for use with UltraVNC Single
|
|
Click and the MSRC4 plugin. It may not be needed on recent SC (e.g. from
|
|
~2009 and later; select "MSRC4" for these newer ones.)
|
|
|
|
You can also specify pw=my-password instead of a keyfile. Use single quotes
|
|
pw='....' if the password contains shell meta-characters `!$&*(){}[]|;<>?
|
|
|
|
Use the literal string 'pw=VNCPASSWD' to have the VNC password that you
|
|
entered into the 'VNC Password:' be used for the pw=...
|
|
|
|
SSL and SSH tunnels do not apply in this mode (any settings are ignored.)
|
|
|
|
Proxying works in this mode, as well as Reverse Connections (Listen)
|
|
|
|
The choice "SecureVNC" refers to the SecureVNC Plugin using 128 bit AES or
|
|
ARC4 with 2048 bit RSA key exchange described here:
|
|
|
|
http://adamwalling.com/SecureVNC
|
|
|
|
Note in its default mode SecureVNC is *Vulnerable* to Man-In-The-Middle attacks
|
|
(encryption but no server authentication) so do not use it with critical data.
|
|
In SecureVNC mode you do not need to supply a 'Ultra DSM Keyfile'. However,
|
|
if you DO supply a keyfile filename (recommended) if that file does not exist
|
|
you will be prompted if you want to save the UltraVNC server's RSA key in it.
|
|
The key's MD5 checksum is displayed so that you can verify that the key is
|
|
trusted. One way to print out the SecureVNC public key MD5 checksum is:
|
|
|
|
openssl rsa -inform DER -outform DER -pubout -in ./Server_SecureVNC.pkey | dd bs=1 skip=24 | md5sum
|
|
|
|
Then on subsequent connections, if you continue to specify this filename, the
|
|
SecureVNCPlugin server's RSA key will be checked against the file's contents
|
|
and if they differ the connection will be dropped.
|
|
|
|
NOTE, However, if the SecureVNC keyfile ends in the string 'ClientAuth.pkey'
|
|
then its contents are used for SecureVNC's normal Client Authentication dialog
|
|
(you need to use Windows SecureVNCPlugin to generate this file on the server
|
|
side, it is usually called "Viewer_ClientAuth.pkey", and then safely copy it
|
|
to the viewer side.) If you want to do BOTH Client Auth and server RSA key
|
|
storing (recommended), have the keyfile end in 'ClientAuth.pkey.rsa'; that way
|
|
the file will be used for storing the server RSA key and then the '.rsa' is
|
|
trimmed off and the remainder used for the SecureVNC Client Auth data filename.
|
|
|
|
Note that despite its intentions, Client Authentication in the FIRST release of
|
|
SecureVNC is still susceptible to Man-In-The-Middle attacks. Even when that
|
|
is fixed, SecureVNC Client Authentication is still susceptible to "spoofing"
|
|
attacks where the viewer user may be tricked into revealing his VNC or MS-Logon
|
|
password if his connection is intercepted. It is recommended you verify and
|
|
save the Server key (see above) in addition to using Client Authentication.
|
|
|
|
UltraVNC DSM encryption modes are currently experimental because unfortunately
|
|
the UltraVNC DSM plugin also modifies the RFB protocol(!), and so the SSVNC
|
|
vncviewer had to be modified to support it. The tight, zlib, and some minor
|
|
encodings currently do not work in this mode and are disabled.
|
|
|
|
Note that this mode also requires the utility tool named 'ultravnc_dsm_helper'
|
|
that should be included in your SSVNC kit.
|
|
|
|
Select 'Non-Ultra DSM' to use symmetric encryption to a Non-UltraVNC server via
|
|
a supported symmetric key cipher. x11vnc supports symmetric encryption via,
|
|
e.g., "x11vnc -enc aesv2:./my.key". Extra ciphers are enabled for this mode
|
|
(e.g. blowfish and 3des). 'UVNC SC' and SecureVNC do not apply in this mode.
|
|
|
|
Note for the Non-Ultra DSM case it will also work with any VNC Viewer
|
|
(i.e. selected by Options -> Advanced -> Change VNC Viewer) not only the
|
|
supplied SSVNC vncviewer.
|
|
|
|
For experts: You can also set the random salt size and initialization vector
|
|
size in Salt,IV for example "8,16". See the x11vnc and 'ultravnc_dsm_helper
|
|
-help' documentation for more info on this.
|
|
}
|
|
|
|
.ultradsm.f.t insert end $msg
|
|
|
|
frame .ultradsm.path
|
|
label .ultradsm.path.l -text "Ultra DSM Keyfile:"
|
|
entry .ultradsm.path.e -width 40 -textvariable ultra_dsm_file
|
|
button .ultradsm.path.b -text "Browse..." -command {set_ultra_dsm_file .ultradsm}
|
|
|
|
pack .ultradsm.path.l -side left
|
|
pack .ultradsm.path.e -side left -expand 1 -fill x
|
|
pack .ultradsm.path.b -side left
|
|
|
|
frame .ultradsm.key
|
|
label .ultradsm.key.l -text "Type of Key: "
|
|
radiobutton .ultradsm.key.guess -pady 1 -anchor w -variable ultra_dsm_type -value guess \
|
|
-text "Guess"
|
|
radiobutton .ultradsm.key.arc4 -pady 1 -anchor w -variable ultra_dsm_type -value arc4 \
|
|
-text "ARC4"
|
|
|
|
radiobutton .ultradsm.key.aesv2 -pady 1 -anchor w -variable ultra_dsm_type -value aesv2 \
|
|
-text "AESV2"
|
|
|
|
radiobutton .ultradsm.key.msrc4 -pady 1 -anchor w -variable ultra_dsm_type -value msrc4 \
|
|
-text "MSRC4"
|
|
|
|
radiobutton .ultradsm.key.msrc4_sc -pady 1 -anchor w -variable ultra_dsm_type -value msrc4_sc \
|
|
-text "UVNC SC"
|
|
|
|
radiobutton .ultradsm.key.securevnc -pady 1 -anchor w -variable ultra_dsm_type -value securevnc \
|
|
-text "SecureVNC"
|
|
|
|
pack .ultradsm.key.l -side left
|
|
pack .ultradsm.key.guess -side left
|
|
pack .ultradsm.key.arc4 -side left
|
|
pack .ultradsm.key.aesv2 -side left
|
|
pack .ultradsm.key.msrc4 -side left
|
|
pack .ultradsm.key.msrc4_sc -side left
|
|
pack .ultradsm.key.securevnc -side left
|
|
|
|
frame .ultradsm.nou
|
|
checkbutton .ultradsm.nou.cb -text "Non-Ultra DSM" -variable ultra_dsm_noultra -command update_no_ultra_dsm
|
|
radiobutton .ultradsm.nou.bf -pady 1 -anchor w -variable ultra_dsm_type -value blowfish \
|
|
-text "Blowfish"
|
|
|
|
radiobutton .ultradsm.nou.des3 -pady 1 -anchor w -variable ultra_dsm_type -value 3des \
|
|
-text "3DES"
|
|
|
|
radiobutton .ultradsm.nou.aes -pady 1 -anchor w -variable ultra_dsm_type -value "aes-cfb" \
|
|
-text "AES-CFB"
|
|
|
|
radiobutton .ultradsm.nou.aes256 -pady 1 -anchor w -variable ultra_dsm_type -value "aes256" \
|
|
-text "AES-256"
|
|
|
|
label .ultradsm.nou.l -text " Salt,IV"
|
|
entry .ultradsm.nou.e -width 6 -textvariable ultra_dsm_salt
|
|
|
|
pack .ultradsm.nou.cb -side left
|
|
pack .ultradsm.nou.bf -side left
|
|
pack .ultradsm.nou.des3 -side left
|
|
pack .ultradsm.nou.aes -side left
|
|
pack .ultradsm.nou.aes256 -side left
|
|
pack .ultradsm.nou.l -side left
|
|
pack .ultradsm.nou.e -side left -expand 0
|
|
|
|
update_no_ultra_dsm
|
|
|
|
button .ultradsm.cancel -text "Cancel" -command {destroy .ultradsm; set ultra_dsm 0}
|
|
bind .ultradsm <Escape> {destroy .ultradsm; set ultra_dsm 0}
|
|
wm protocol .ultradsm WM_DELETE_WINDOW {destroy .ultradsm; set ultra_dsm 0}
|
|
button .ultradsm.done -text "Done" -command {destroy .ultradsm; catch {raise .oa}}
|
|
bind .ultradsm.path.e <Return> {destroy .ultradsm; catch {raise .oa}}
|
|
|
|
pack .ultradsm.f .ultradsm.path .ultradsm.key .ultradsm.nou .ultradsm.cancel .ultradsm.done -side top -fill x
|
|
|
|
center_win .ultradsm
|
|
wm resizable .ultradsm 1 0
|
|
|
|
focus .ultradsm.path.e
|
|
}
|
|
|
|
proc ssh_known_hosts_dialog {} {
|
|
global ssh_known_hosts ssh_known_hosts_filename
|
|
|
|
toplev .sshknownhosts
|
|
wm title .sshknownhosts "Private SSH KnownHosts file"
|
|
|
|
global help_font
|
|
set h 31
|
|
if [small_height] {
|
|
set h 23
|
|
}
|
|
scroll_text .sshknownhosts.f 80 $h
|
|
|
|
set msg {
|
|
Private SSH KnownHosts file:
|
|
|
|
On Unix in SSH mode, let the user specify a non-default
|
|
ssh known_hosts file to be used only by the current profile.
|
|
This is the UserKnownHostsFile ssh option and is described in the
|
|
ssh_config(1) man page. This is useful to avoid proxy 'localhost'
|
|
SSH key collisions.
|
|
|
|
Normally one should simply let ssh use its default file
|
|
~/.ssh/known_hosts for tracking SSH keys. The only problem with
|
|
that happens when multiple SSVNC connections use localhost tunnel
|
|
port redirections. These make ssh connect to 'localhost' on some
|
|
port (where the proxy is listening.) Then the different keys
|
|
from the multiple ssh servers collide when ssh saves them under
|
|
'localhost' in ~/.ssh/known_hosts.
|
|
|
|
So if you are using a proxy with SSVNC or doing a "double SSH
|
|
gateway" your ssh will connect to a proxy port on localhost, and you
|
|
should set a private KnownHosts file for that connection profile.
|
|
This is secure and avoids man-in-the-middle attack (as long as
|
|
you actually verify the initial save of the SSH key!)
|
|
|
|
The default file location will be:
|
|
|
|
~/.vnc/ssh_known_hosts/profile-name.known
|
|
|
|
but you can choose any place you like. It must of course be
|
|
unique and not shared with another ssh connection otherwise they
|
|
both may complain about the key for 'localhost' changing, etc.
|
|
}
|
|
|
|
.sshknownhosts.f.t insert end $msg
|
|
|
|
frame .sshknownhosts.path
|
|
label .sshknownhosts.path.l -text "SSH KnownHosts file:"
|
|
entry .sshknownhosts.path.e -width 40 -textvariable ssh_known_hosts_filename
|
|
button .sshknownhosts.path.b -text "Browse..." -command {set_ssh_known_hosts_file .sshknownhosts}
|
|
|
|
pack .sshknownhosts.path.l -side left
|
|
pack .sshknownhosts.path.e -side left -expand 1 -fill x
|
|
pack .sshknownhosts.path.b -side left
|
|
|
|
button .sshknownhosts.cancel -text "Cancel" -command {destroy .sshknownhosts; set ssh_known_hosts 0}
|
|
bind .sshknownhosts <Escape> {destroy .sshknownhosts; set ssh_known_hosts 0}
|
|
wm protocol .sshknownhosts WM_DELETE_WINDOW {destroy .sshknownhosts; set ssh_known_hosts 0}
|
|
button .sshknownhosts.done -text "Done" -command {destroy .sshknownhosts; catch {raise .oa}}
|
|
bind .sshknownhosts.path.e <Return> {destroy .sshknownhosts; catch {raise .oa}}
|
|
|
|
pack .sshknownhosts.f .sshknownhosts.path .sshknownhosts.cancel .sshknownhosts.done -side top -fill x
|
|
|
|
center_win .sshknownhosts
|
|
wm resizable .sshknownhosts 1 0
|
|
|
|
focus .sshknownhosts.path.e
|
|
}
|
|
|
|
proc ssh_sec_dialog {} {
|
|
global ssh_local_protection
|
|
|
|
toplev .sshsec
|
|
wm title .sshsec "SSH Local Port Protections"
|
|
|
|
global help_font
|
|
eval text .sshsec.t -width 80 -height 28 $help_font
|
|
|
|
apply_bg .sshsec.t
|
|
|
|
set msg {
|
|
See the discussion of "Untrusted Local Users" in the main 'Help'
|
|
panel for info about users who are able to log into the workstation
|
|
you run SSVNC on and might try to use your encrypted tunnel to gain
|
|
access to the remote VNC machine.
|
|
|
|
On Unix, for SSH tunnels we have an LD_PRELOAD hack (lim_accept.so)
|
|
that will limit ssh from accepting any local redirection connections
|
|
after the first one or after 35 seconds, whichever comes first.
|
|
The first SSH port redirection connection is intended to be the one
|
|
that tunnels your VNC Viewer to reach the remote server.
|
|
|
|
You can adjust these defaults LIM_ACCEPT=1 LIM_ACCEPT_TIME=35 by
|
|
setting those env. vars. to different values.
|
|
|
|
Note that there is still a window of a few seconds the Untrusted
|
|
Local User can try to connect before your VNC Viewer does. So this
|
|
method is far from perfect. But once your VNC session is established,
|
|
he should be blocked out. Test to make sure blocking is taking place.
|
|
|
|
Do not use this option if you are doing SSH Service redirections
|
|
'Additional Port Redirections (via SSH)' that redirect a local port
|
|
to the remote server via ssh -L.
|
|
|
|
Note that if the shared object "lim_accept.so" cannot be found,
|
|
this option has no effect. Watch the output in the terminal for
|
|
the "SSVNC_LIM_ACCEPT_PRELOAD" setting.
|
|
}
|
|
.sshsec.t insert end $msg
|
|
|
|
button .sshsec.cancel -text "Cancel" -command {set ssh_local_protection 0; destroy .sshsec}
|
|
bind .sshsec <Escape> {set ssh_local_protection 0; destroy .sshsec}
|
|
wm protocol .sshsec WM_DELETE_WINDOW {set ssh_local_protection 0; destroy .sshsec}
|
|
button .sshsec.done -text "Done" -command {destroy .sshsec}
|
|
|
|
pack .sshsec.t .sshsec.cancel .sshsec.done -side top -fill x
|
|
|
|
center_win .sshsec
|
|
wm resizable .sshsec 1 0
|
|
}
|
|
|
|
proc multilisten_dialog {} {
|
|
global multiple_listen
|
|
|
|
toplev .multil
|
|
wm title .multil "Multiple LISTEN Connections"
|
|
|
|
global help_font
|
|
set h 36
|
|
if [small_height] {
|
|
set h 30
|
|
}
|
|
eval text .multil.t -width 84 -height $h $help_font
|
|
|
|
apply_bg .multil.t
|
|
|
|
set msg {
|
|
Set this option to allow SSVNC (when in LISTEN / Reverse connections
|
|
mode) to allow multiple VNC servers to connect at the same time and
|
|
so display each of their desktops on your screen at the same time.
|
|
|
|
This option only applies on Unix or MaOSX when using the supplied
|
|
SSVNC vncviewer. If you specify your own VNC Viewer it has no effect.
|
|
|
|
On Windows (only the stock TightVNC viewer is provided) it has no effect
|
|
because the Windows SSVNC can ONLY do "Multiple LISTEN Connections".
|
|
Similarly on MacOSX if the COTVNC viewer is used there is no effect.
|
|
|
|
Rationale: To play it safe, the Unix vncviewer provided by SSVNC
|
|
(ssvncviewer) only allows one LISTEN reverse connection at a time.
|
|
This is to prohibit malicious people on the network from depositing
|
|
as many desktops on your screen as he likes, even if you are already
|
|
connected to VNC server you desire.
|
|
|
|
For example, perhaps the malicious user could trick you into typing
|
|
a password into the desktop he displays on your screen.
|
|
|
|
This protection is not perfect, because the malicious user could
|
|
try to reverse connect to you before the correct VNC server reverse
|
|
connects to you. This is even more of a problem if you keep your
|
|
SSVNC viewer in LISTEN mode but unconnected for long periods of time.
|
|
Pay careful attention in this case if you are to supplying sensitive
|
|
information to the remote desktop.
|
|
|
|
Enable 'Multiple LISTEN Connections' if you want to disable the default
|
|
protection in the Unix SSVNC vncviewer; i.e. allow multiple reverse
|
|
connections simultaneously (all vnc viewers we know of do this by default)
|
|
|
|
For more control, do not select 'Multiple LISTEN Connections', but
|
|
rather set the env. var SSVNC_MULTIPLE_LISTEN=MAX:n to limit the number
|
|
of simultaneous reverse connections to "n"
|
|
}
|
|
.multil.t insert end $msg
|
|
|
|
button .multil.cancel -text "Cancel" -command {set multiple_listen 0; destroy .multil}
|
|
bind .multil <Escape> {set multiple_listen 0; destroy .multil}
|
|
wm protocol .multil WM_DELETE_WINDOW {set multiple_listen 0; destroy .multil}
|
|
button .multil.done -text "Done" -command {destroy .multil}
|
|
|
|
pack .multil.t .multil.cancel .multil.done -side top -fill x
|
|
|
|
center_win .multil
|
|
wm resizable .multil 1 0
|
|
}
|
|
|
|
proc use_grab_dialog {} {
|
|
global usg_grab
|
|
|
|
toplev .usegrb
|
|
wm title .usegrb "Use XGrabServer (for fullscreen)"
|
|
|
|
global help_font
|
|
eval text .usegrb.t -width 85 -height 29 $help_font
|
|
|
|
apply_bg .usegrb.t
|
|
|
|
set msg {
|
|
On Unix, some Window managers and some Desktops make it difficult for the
|
|
SSVNC Unix VNC viewer to go into full screen mode (F9) and/or return.
|
|
|
|
Sometimes one can go into full screen mode, but then your keystrokes or
|
|
Mouse actions do not get through. This can leave you trapped because you
|
|
cannot inject input (F9 again) to get out of full screen mode. (Tip:
|
|
press Ctrl-Alt-F2 for a console login shell; then kill your vncviewer
|
|
process, e.g. pkill vncviewer; then Alt-F7 to get back to your desktop)
|
|
|
|
We have seen this in some very old Window managers (e.g. fvwm2 circa
|
|
1998) and some very new Desktops (e.g. GNOME circa 2008). We try
|
|
to work around the problem on recent desktops by using the NEW_WM
|
|
interface, but if you use Fullscreen, you may need to use this option.
|
|
|
|
The default for the SSVNC Unix VNC viewer is '-grabkbd' mode where it will
|
|
try to exclusively grab the keyboard. This often works correctly.
|
|
|
|
However if Fullscreen is not working properly, try setting this
|
|
'Use XGrabServer' option to enable '-graball' mode where it tries to grab
|
|
the entire X server. This usually works, but can be a bit flakey.
|
|
|
|
Sometimes toggling F9 a few times gets lets the vncviewer fill the whole
|
|
screen. Sometimes tapping F9 very quickly gets it to snap in. If GNOME
|
|
(or whatever desktop) is still showing its taskbars, it is recommended
|
|
you toggle F9 until it isn't. Otherwise, it is not clear who gets the input.
|
|
|
|
Best of luck.
|
|
}
|
|
.usegrb.t insert end $msg
|
|
|
|
button .usegrb.cancel -text "Cancel" -command {set use_grab 0; destroy .usegrb}
|
|
bind .usegrb <Escape> {set use_grab 0; destroy .usegrb}
|
|
wm protocol .usegrb WM_DELETE_WINDOW {set use_grab 0; destroy .usegrb}
|
|
button .usegrb.done -text "Done" -command {destroy .usegrb}
|
|
|
|
pack .usegrb.t .usegrb.cancel .usegrb.done -side top -fill x
|
|
|
|
center_win .usegrb
|
|
wm resizable .usegrb 1 0
|
|
}
|
|
|
|
|
|
proc find_netcat {} {
|
|
global is_windows
|
|
|
|
set nc ""
|
|
|
|
if {! $is_windows} {
|
|
set nc [in_path "netcat"]
|
|
if {$nc == ""} {
|
|
set nc [in_path "nc"]
|
|
}
|
|
} else {
|
|
set try "netcat.exe"
|
|
if [file exists $try] {
|
|
set nc $try
|
|
}
|
|
}
|
|
return $nc
|
|
}
|
|
|
|
proc pk_expand {cmd host} {
|
|
global tcl_platform
|
|
set secs [clock seconds]
|
|
set msecs [clock clicks -milliseconds]
|
|
set user $tcl_platform(user)
|
|
if [regexp {%IP} $cmd] {
|
|
set ip [guess_ip]
|
|
if {$ip == ""} {
|
|
set ip "unknown"
|
|
}
|
|
regsub -all {%IP} $cmd $ip cmd
|
|
}
|
|
if [regexp {%NAT} $cmd] {
|
|
set ip [guess_nat_ip]
|
|
regsub -all {%NAT} $cmd $ip cmd
|
|
}
|
|
regsub -all {%HOST} $cmd $host cmd
|
|
regsub -all {%USER} $cmd $user cmd
|
|
regsub -all {%SECS} $cmd $secs cmd
|
|
regsub -all {%MSECS} $cmd $msecs cmd
|
|
|
|
return $cmd
|
|
}
|
|
|
|
proc backtick_expand {str} {
|
|
set str0 $str
|
|
set collect ""
|
|
set count 0
|
|
while {[regexp {^(.*)`([^`]+)`(.*)$} $str mv p1 cmd p2]} {
|
|
set out [eval exec $cmd]
|
|
set str "$p1$out$p2"
|
|
incr count
|
|
if {$count > 10} {
|
|
break
|
|
}
|
|
}
|
|
return $str
|
|
}
|
|
|
|
proc read_from_pad {file} {
|
|
set fh ""
|
|
if {[catch {set fh [open $file "r"]}] != 0} {
|
|
return "FAIL"
|
|
}
|
|
|
|
set accum ""
|
|
set match ""
|
|
while {[gets $fh line] > -1} {
|
|
if [regexp {^[ \t]*#} $line] {
|
|
append accum "$line\n"
|
|
} elseif [regexp {^[ \t]*$} $line] {
|
|
append accum "$line\n"
|
|
} elseif {$match == ""} {
|
|
set match $line
|
|
append accum "# $line\n"
|
|
} else {
|
|
append accum "$line\n"
|
|
}
|
|
}
|
|
|
|
close $fh
|
|
|
|
if {$match == ""} {
|
|
return "FAIL"
|
|
}
|
|
|
|
if {[catch {set fh [open $file "w"]}] != 0} {
|
|
return "FAIL"
|
|
}
|
|
|
|
puts -nonewline $fh $accum
|
|
|
|
return $match
|
|
}
|
|
|
|
proc do_port_knock {hp mode} {
|
|
global use_port_knocking port_knocking_list
|
|
global is_windows
|
|
|
|
if {! $use_port_knocking} {
|
|
return 1
|
|
}
|
|
if {$port_knocking_list == ""} {
|
|
return 1
|
|
}
|
|
set list $port_knocking_list
|
|
|
|
if {$mode == "finish"} {
|
|
if {! [regexp {FINISH} $list]} {
|
|
mesg "PortKnock(finish): done"
|
|
return 1
|
|
} else {
|
|
regsub {^.*FINISH} $list "" list
|
|
}
|
|
} elseif {$mode == "start"} {
|
|
if {[regexp {FINISH} $list]} {
|
|
regsub {FINISH.*$} $list "" list
|
|
}
|
|
}
|
|
|
|
set default_delay 150
|
|
|
|
set host [string trim $hp]
|
|
# XXX host_part
|
|
regsub {^vnc://} $host "" host
|
|
regsub {^.*@} $host "" host
|
|
regsub {:[0-9][0-9]*$} $host "" host
|
|
set host0 [string trim $host]
|
|
|
|
if {$host0 == ""} {
|
|
bell
|
|
mesg "PortKnock: No host: $hp"
|
|
return 0
|
|
}
|
|
|
|
set m ""
|
|
|
|
if [regexp {PAD=([^\n]+)} $list mv padfile] {
|
|
set tlist [read_from_pad $padfile]
|
|
set tlist [string trim $tlist]
|
|
if {$tlist == "" || $tlist == "FAIL"} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error \
|
|
-message "Failed to read entry from $padfile" \
|
|
-title "Error: Padfile $padfile"
|
|
return 0
|
|
}
|
|
regsub -all {PAD=([^\n]+)} $list $tlist list
|
|
}
|
|
|
|
set spl ",\n\r"
|
|
if [regexp {CMD=} $list] {set spl "\n\r"}
|
|
if [regexp {CMDX=} $list] {set spl "\n\r"}
|
|
if [regexp {SEND=} $list] {set spl "\n\r"}
|
|
if [regexp {SENDX=} $list] {set spl "\n\r"}
|
|
|
|
set i 0
|
|
set pi 0
|
|
|
|
foreach line [split $list $spl] {
|
|
set line [string trim $line]
|
|
set line0 $line
|
|
|
|
if {$line == ""} {
|
|
continue
|
|
}
|
|
if [regexp {^#} $line] {
|
|
continue
|
|
}
|
|
|
|
if [regexp {^sleep[ \t][ \t]*([0-9][0-9]*)} $line mv sl] {
|
|
set m "PortKnock: sleep $sl"
|
|
mesg $m
|
|
after $sl
|
|
continue
|
|
}
|
|
if [regexp {^delay[ \t][ \t]*([0-9][0-9]*)} $line mv sl] {
|
|
set m "PortKnock: delay=$sl"
|
|
mesg $m
|
|
set default_delay $sl
|
|
continue
|
|
}
|
|
|
|
if [regexp {^CMD=(.*)} $line mv cmd] {
|
|
set m "PortKnock: CMD: $cmd"
|
|
mesg $m
|
|
eval exec $cmd
|
|
continue
|
|
}
|
|
if [regexp {^CMDX=(.*)} $line mv cmd] {
|
|
set cmd [pk_expand $cmd $host0]
|
|
set m "PortKnock: CMDX: $cmd"
|
|
mesg $m
|
|
eval exec $cmd
|
|
continue
|
|
}
|
|
|
|
if [regexp {`} $line] {
|
|
#set line [backtick_expand $line]
|
|
}
|
|
|
|
set snd ""
|
|
if [regexp {^(.*)SEND=(.*)$} $line mv line snd] {
|
|
set line [string trim $line]
|
|
set snd [string trim $snd]
|
|
regsub -all {%NEWLINE} $snd "\n" snd
|
|
} elseif [regexp {^(.*)SENDX=(.*)$} $line mv line snd] {
|
|
set line [string trim $line]
|
|
set snd [string trim $snd]
|
|
set snd [pk_expand $snd $host0]
|
|
regsub -all {%NEWLINE} $snd "\n" snd
|
|
}
|
|
|
|
set udp 0
|
|
if [regexp -nocase {[/:]udp} $line] {
|
|
set udp 1
|
|
regsub -all -nocase {[/:]udp} $line " " line
|
|
set line [string trim $line]
|
|
}
|
|
regsub -all -nocase {[/:]tcp} $line " " line
|
|
set line [string trim $line]
|
|
|
|
set delay 0
|
|
if [regexp {^(.*)[ \t][ \t]*([0-9][0-9]*)$} $line mv first delay] {
|
|
set line [string trim $first]
|
|
}
|
|
|
|
if {[regexp {^(.*):([0-9][0-9]*)$} $line mv host port]} {
|
|
;
|
|
} else {
|
|
set host $host0
|
|
set port $line
|
|
}
|
|
set host [string trim $host]
|
|
set port [string trim $port]
|
|
|
|
if {$host == ""} {
|
|
set host $host0
|
|
}
|
|
|
|
if {$port == ""} {
|
|
bell
|
|
set m "PortKnock: No port found: \"$line0\""
|
|
mesg $m
|
|
return 0
|
|
}
|
|
if {! [regexp {^[0-9][0-9]*$} $port]} {
|
|
bell
|
|
set m "PortKnock: Invalid port: \"$port\""
|
|
mesg $m
|
|
return 0
|
|
}
|
|
regsub {,.*$} $host "" host
|
|
if {[regexp {[ \t]} $host]} {
|
|
bell
|
|
set m "PortKnock: Invalid host: \"$host\""
|
|
mesg $m
|
|
return 0
|
|
}
|
|
if {! [regexp {^[-A-z0-9_.][-A-z0-9_.]*$} $host]} {
|
|
bell
|
|
set m "PortKnock: Invalid host: \"$host\""
|
|
mesg $m
|
|
return 0
|
|
}
|
|
|
|
set nc ""
|
|
if {$udp || $snd != ""} {
|
|
set nc [find_netcat]
|
|
if {$nc == ""} {
|
|
bell
|
|
set m "PortKnock: UDP: netcat(1) not found"
|
|
mesg $m
|
|
after 1000
|
|
continue
|
|
}
|
|
}
|
|
|
|
if {$snd != ""} {
|
|
global env
|
|
set pfile "payload$pi.txt"
|
|
if {! $is_windows} {
|
|
set pfile "$env(SSVNC_HOME)/.$pfile"
|
|
}
|
|
set pfiles($pi) $pfile
|
|
incr pi
|
|
set fh [open $pfile "w"]
|
|
puts -nonewline $fh "$snd"
|
|
close $fh
|
|
|
|
set m "PortKnock: SEND: $host $port"
|
|
mesg $m
|
|
if {$is_windows} {
|
|
if {$udp} {
|
|
catch {exec $nc -d -u -w 1 "$host" "$port" < $pfile &}
|
|
} else {
|
|
catch {exec $nc -d -w 1 "$host" "$port" < $pfile &}
|
|
}
|
|
} else {
|
|
if {$udp} {
|
|
catch {exec $nc -u -w 1 "$host" "$port" < $pfile &}
|
|
} else {
|
|
catch {exec $nc -w 1 "$host" "$port" < $pfile &}
|
|
}
|
|
}
|
|
catch {after 50; file delete $pfile}
|
|
|
|
} elseif {$udp} {
|
|
set m "PortKnock: UDP: $host $port"
|
|
mesg $m
|
|
if {! $is_windows} {
|
|
catch {exec echo a | $nc -u -w 1 "$host" "$port" &}
|
|
} else {
|
|
set fh [open "nc_in.txt" "w"]
|
|
puts $fh "a"
|
|
close $fh
|
|
catch {exec $nc -d -u -w 1 "$host" "$port" < "nc_in.txt" &}
|
|
}
|
|
} else {
|
|
set m "PortKnock: TCP: $host $port"
|
|
mesg $m
|
|
set s ""
|
|
set emess ""
|
|
set rc [catch {set s [socket -async $host $port]} emess]
|
|
if {$rc != 0} {
|
|
raise .
|
|
tk_messageBox -type ok -icon error -message $emess -title "Error: socket -async $host $port"
|
|
}
|
|
set sockets($i) $s
|
|
# seems we have to close it immediately to avoid multiple SYN's.
|
|
# does not help on Win9x.
|
|
catch {after 30; close $s};
|
|
incr i
|
|
}
|
|
|
|
if {$delay == 0} {
|
|
if {$default_delay > 0} {
|
|
after $default_delay
|
|
}
|
|
} elseif {$delay > 0} {
|
|
after $delay
|
|
}
|
|
}
|
|
|
|
if {0} {
|
|
for {set j 0} {$j < $i} {incr j} {
|
|
set $s $sockets($j)
|
|
if {$s != ""} {
|
|
catch {close $s}
|
|
}
|
|
}
|
|
}
|
|
for {set j 0} {$j < $pi} {incr j} {
|
|
set f $pfiles($j)
|
|
if {$f != ""} {
|
|
if [file exists $f] {
|
|
after 100
|
|
}
|
|
catch {file delete $f}
|
|
}
|
|
}
|
|
if {$is_windows} {
|
|
catch {file delete "nc_in.txt"}
|
|
}
|
|
if {$m != ""} {
|
|
set m "$m,"
|
|
}
|
|
if {$mode == "finish"} {
|
|
mesg "PortKnock(finish): done"
|
|
} else {
|
|
mesg "PortKnock: done"
|
|
}
|
|
return 1
|
|
}
|
|
|
|
proc port_knocking_dialog {} {
|
|
toplev .pk
|
|
wm title .pk "Port Knocking"
|
|
global use_port_knocking port_knocking_list
|
|
|
|
global help_font
|
|
|
|
global uname
|
|
|
|
set h 35
|
|
if [small_height] {
|
|
set h 22
|
|
} elseif {$uname == "Darwin"} {
|
|
set h 25
|
|
}
|
|
scroll_text .pk.f 85 $h
|
|
|
|
set msg {
|
|
Description:
|
|
|
|
Port Knocking is where a network connection to a service is not provided
|
|
to just any client, but rather only to those that immediately prior to
|
|
connecting send a more or less secret pattern of connections to other
|
|
ports on the firewall.
|
|
|
|
Somewhat like "knocking" on the door with the correct sequence before it
|
|
being opened (but not necessarily letting you in yet). It is also possible
|
|
to have a single encrypted packet (e.g. UDP) payload communicate with the
|
|
firewall instead of knocking on a sequence of ports.
|
|
|
|
Only after the correct sequence of ports is observed by the firewall does
|
|
it allow the IP address of the client to attempt to connect to the service.
|
|
|
|
So, for example, instead of allowing any host on the internet to connect
|
|
to your SSH service and then try to login with a username and password, the
|
|
client first must "tickle" your firewall with the correct sequence of ports.
|
|
Only then will it be allowed to connect to your SSH service at all.
|
|
|
|
This does not replace the authentication and security of SSH, it merely
|
|
puts another layer of protection around it. E.g., suppose an exploit for
|
|
SSH was discovered, you would most likely have more time to fix/patch
|
|
the problem than if any client could directly connect to your SSH server.
|
|
|
|
For more information http://www.portknocking.org/ and
|
|
http://www.linuxjournal.com/article/6811
|
|
|
|
|
|
Tip:
|
|
|
|
If you just want to use the Port Knocking for an SSH shell and not
|
|
for a VNC tunnel, then specify something like "user@hostname cmd=SHELL"
|
|
(or "user@hostname cmd=PUTTY" on Windows) in the VNC Host:Display entry box
|
|
on the main panel. This will do everything short of starting the viewer.
|
|
A shortcut for this is Ctrl-S as long as user@hostname is present.
|
|
|
|
|
|
Specifying the Knocks:
|
|
|
|
In the text area below "Supply port knocking pattern" you put in the pattern
|
|
of "knocks" needed for this connection. You can separate the knocks by
|
|
commas or put them one per line.
|
|
|
|
Each "knock" is of this form:
|
|
|
|
[host:]port[/udp] [delay]
|
|
|
|
In the simplest form just a numerical port, e.g. 5433, is supplied.
|
|
Items inside [...] are optional and described below.
|
|
|
|
The packet is sent to the same host that the VNC (or SSH) connection will
|
|
be made to. If you want it to go to a different host or IP use the [host:]
|
|
prefix. It can be either a hostname or numerical IP.
|
|
|
|
A TCP packet is sent by default.
|
|
|
|
If you need to send a UDP packet, the netcat (aka "nc") program must be
|
|
installed on Unix (tcl/tk does not support udp connections). Indicate this
|
|
with "/udp" following the port number (you can also use "/tcp", but since
|
|
it is the default it is not necessary). (You can also use ":udp" to match
|
|
the knockd syntax). See the example below. For convenience a Windows netcat
|
|
binary is supplied.
|
|
|
|
The last field, [delay], is an optional number of milliseconds to delay
|
|
before continuing on to the next knock.
|
|
|
|
|
|
Examples:
|
|
|
|
5433, 12321, 1661
|
|
|
|
fw.example.com:5433, 12321/udp 3000, 1661 2000
|
|
|
|
fw.example.com:5433
|
|
12321/udp 3000
|
|
1661 2000
|
|
|
|
Note how the first two examples separate their knocks via commas ",".
|
|
The 3rd example is equivalent to the 2nd and splits them up by new lines.
|
|
|
|
Note for each knock any second number (e.g. the "2000" in "1661 2000") is
|
|
a DELAY in milliseconds, not a port number. If you had a comma separating
|
|
them: "1661, 2000" that would mean two separate knocks: one to port 1661
|
|
followed by one to 2000 (with basically no delay between them).
|
|
|
|
In examples 2 and 3, "fw.example.com" represents some machine other than
|
|
the VNC/SSH host. By default, the VNC/SSH host is the one the packet is
|
|
sent to.
|
|
|
|
If one of the items is the string "FINISH", then the part before it is
|
|
used prior to connecting and the part after is used once the connection
|
|
is finished. This can be used, say, to close the firewall port. Example:
|
|
|
|
5433, 12321, FINISH, 7659, 2314
|
|
|
|
(or one can split them up via lines as above.)
|
|
|
|
|
|
Advanced port knock actions:
|
|
|
|
If the string in the text field contains anywhere the strings "CMD=", "CMDX=",
|
|
or "SEND=", then splitting on commas is not done: it is only split on lines.
|
|
|
|
Then, if a line begins CMD=... the string after the = is run as an
|
|
external command. The command could be anything you want, e.g. it could
|
|
be a port-knocking client that does the knocking, perhaps encrypting the
|
|
"knocks" pattern somehow or using a Single Packet Authorization method such
|
|
as http://www.cipherdyne.com/fwknop/
|
|
|
|
Extra quotes (sometimes "'foo bar'") may be needed to preserve spaces in
|
|
command line arguments because the tcl/tk eval(n) command is used. You
|
|
can also use {...} for quoting strings with spaces.
|
|
|
|
If a line begins CMDX=... then before the command is run the following
|
|
tokens are expanded to strings:
|
|
|
|
%IP Current machine's IP address (NAT may make this not useful).
|
|
%NAT Try to get effective IP by contacting http://www.whatismyip.com
|
|
%HOST The remote host of the connection.
|
|
%USER The current user.
|
|
%SECS The current time in seconds (platform dependent).
|
|
%MSECS Platform dependent time having at least millisecond granularity.
|
|
|
|
Lines not matching CMD= or CMDX= are treated as normal port knocks but with
|
|
one exception. If a line ends in SEND=... (i.e. after the [host:]port,
|
|
etc., part) then the string after the = is sent as a payload for the tcp
|
|
or udp connection to [host:]port. netcat is used for these SEND cases
|
|
(and must be available on Unix). If newlines (\n) are needed in the
|
|
SEND string, use %NEWLINE. Sending binary data is not yet supported;
|
|
use CMD= with your own program.
|
|
|
|
|
|
Advanced Examples:
|
|
|
|
CMD=port_knock_client -password wombat33
|
|
CMDX=port_knock_client -password wombat33 -host %HOST -src %NAT
|
|
|
|
fw.example.com:5433/udp SEND=ASDLFKSJDF
|
|
|
|
|
|
More tricks:
|
|
|
|
To temporarily "comment out" a knock, insert a leading "#" character.
|
|
|
|
Use "sleep N" to insert a raw sleep for N milliseconds (e.g. between
|
|
CMD=... items or at the very end of the knocks to wait).
|
|
|
|
If a knock entry matches "delay N" the default delay is set to
|
|
N milliseconds (it is 150 initially).
|
|
|
|
|
|
One Time Pads:
|
|
|
|
If the text contains a (presumably single) line of the form:
|
|
|
|
PAD=/path/to/a/one/time/pad/file
|
|
|
|
then that file is opened and the first non-blank line not beginning
|
|
with "#" is used as the knock pattern. The pad file is rewritten
|
|
with that line starting with a "#" (so it will be skipped next time).
|
|
|
|
The PAD=... string is replaced with the read-in knock pattern line.
|
|
So, if needed, one can preface the PAD=... with "delay N" to set the
|
|
default delay, and one can also put a "sleep N" after the PAD=...
|
|
line to indicate a final sleep. One can also surround the PAD=
|
|
line with other knock and CMD= CMDX= lines, but that usage sounds
|
|
a bit rare. Example:
|
|
|
|
delay 1000
|
|
PAD=C:\My Pads\work-pad1.txt
|
|
sleep 4000
|
|
|
|
|
|
Port knock only:
|
|
|
|
If, in the 'VNC Host:Display' entry, you use "user@hostname cmd=KNOCK"
|
|
then only the port-knocking is performed. A shortcut for this is
|
|
Ctrl-P as long as hostname is present in the entry box. If it
|
|
matches cmd=KNOCKF, i.e. an extra "F", then the port-knocking
|
|
"FINISH" sequence is sent, if any. A shortcut for this Shift-Ctrl-P
|
|
as long as hostname is present.
|
|
}
|
|
.pk.f.t insert end $msg
|
|
|
|
label .pk.info -text "Supply port knocking pattern:" -anchor w -relief ridge
|
|
|
|
eval text .pk.rule -width 80 -height 5 $help_font
|
|
.pk.rule insert end $port_knocking_list
|
|
|
|
button .pk.cancel -text "Cancel" -command {set use_port_knocking 0; destroy .pk}
|
|
bind .pk <Escape> {set use_port_knocking 0; destroy .pk}
|
|
wm protocol .pk WM_DELETE_WINDOW {set use_port_knocking 0; destroy .pk}
|
|
button .pk.done -text "Done" -command {if {$use_port_knocking} {set port_knocking_list [.pk.rule get 1.0 end]}; destroy .pk}
|
|
|
|
pack .pk.done .pk.cancel .pk.rule .pk.info -side bottom -fill x
|
|
pack .pk.f -side top -fill both -expand 1
|
|
|
|
center_win .pk
|
|
}
|
|
|
|
proc choose_desktop_dialog {} {
|
|
toplev .sd
|
|
wm title .sd "Desktop Type"
|
|
global ts_desktop_type choose_desktop
|
|
|
|
global ts_desktop_type_def
|
|
set def "kde"
|
|
if {$ts_desktop_type_def != ""} {
|
|
set def $ts_desktop_type_def
|
|
}
|
|
|
|
if {$ts_desktop_type == ""} {
|
|
set ts_desktop_type $def
|
|
}
|
|
|
|
label .sd.l1 -anchor w -text "Select the type of remote Desktop"
|
|
label .sd.l2 -anchor w -text "for your session (default: $def)"
|
|
|
|
radiobutton .sd.b1 -anchor w -variable ts_desktop_type -value kde -text kde
|
|
radiobutton .sd.b2 -anchor w -variable ts_desktop_type -value gnome -text gnome
|
|
radiobutton .sd.b3 -anchor w -variable ts_desktop_type -value Xsession -text cde
|
|
radiobutton .sd.b4 -anchor w -variable ts_desktop_type -value mwm -text mwm
|
|
radiobutton .sd.b5 -anchor w -variable ts_desktop_type -value wmaker -text wmaker
|
|
radiobutton .sd.b6 -anchor w -variable ts_desktop_type -value xfce -text xfce
|
|
radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value enlightenment -text enlightenment
|
|
radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value twm -text twm
|
|
radiobutton .sd.b9 -anchor w -variable ts_desktop_type -value failsafe -text failsafe
|
|
|
|
button .sd.cancel -text "Cancel" -command {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
|
|
bind .sd <Escape> {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
|
|
wm protocol .sd WM_DELETE_WINDOW {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
|
|
button .sd.done -text "Done" -command {destroy .sd}
|
|
|
|
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
|
|
|
|
center_win .sd
|
|
}
|
|
|
|
proc choose_size_dialog {} {
|
|
toplev .sz
|
|
wm title .sz "Desktop Size"
|
|
global ts_desktop_size ts_desktop_depth choose_desktop_geom
|
|
|
|
set def1 "1280x1024"
|
|
set def2 "16"
|
|
|
|
global ts_desktop_size_def ts_desktop_depth_def
|
|
if {$ts_desktop_size_def != ""} {
|
|
set def1 $ts_desktop_size_def
|
|
}
|
|
if {$ts_desktop_depth_def != ""} {
|
|
set def2 $ts_desktop_depth_def
|
|
}
|
|
|
|
if {$ts_desktop_size == ""} {
|
|
set ts_desktop_size $def1
|
|
}
|
|
if {$ts_desktop_depth == ""} {
|
|
set ts_desktop_depth $def2
|
|
}
|
|
|
|
label .sz.l1 -anchor w -text "Select the Size and Color depth"
|
|
label .sz.l2 -anchor w -text "for your Desktop session."
|
|
label .sz.l3 -anchor w -text "Default: $def1 and $def2 bits/pixel."
|
|
|
|
label .sz.g0 -anchor w -text "Width x Height:" -relief groove
|
|
|
|
radiobutton .sz.g1 -anchor w -variable ts_desktop_size -value "640x480" -text " 640x480"
|
|
radiobutton .sz.g2 -anchor w -variable ts_desktop_size -value "800x600" -text " 800x600"
|
|
radiobutton .sz.g3 -anchor w -variable ts_desktop_size -value "1024x768" -text " 1024x768"
|
|
radiobutton .sz.g4 -anchor w -variable ts_desktop_size -value "1280x1024" -text "1280x1024"
|
|
radiobutton .sz.g5 -anchor w -variable ts_desktop_size -value "1400x1050" -text "1400x1050"
|
|
radiobutton .sz.g6 -anchor w -variable ts_desktop_size -value "1600x1200" -text "1600x1200"
|
|
radiobutton .sz.g7 -anchor w -variable ts_desktop_size -value "1920x1200" -text "1920x1200"
|
|
|
|
frame .sz.c
|
|
label .sz.c.l -anchor w -text "Custom:"
|
|
entry .sz.c.e -width 10 -textvariable ts_desktop_size
|
|
pack .sz.c.l -side left
|
|
pack .sz.c.e -side left -expand 1 -fill x
|
|
bind .sz.c.e <Return> {destroy .sz}
|
|
|
|
label .sz.d0 -anchor w -text "Color Depth:" -relief groove
|
|
|
|
radiobutton .sz.d1 -anchor w -variable ts_desktop_depth -value "8" -text " 8 bits/pixel"
|
|
radiobutton .sz.d2 -anchor w -variable ts_desktop_depth -value "16" -text "16 bits/pixel"
|
|
radiobutton .sz.d3 -anchor w -variable ts_desktop_depth -value "24" -text "24 bits/pixel"
|
|
|
|
button .sz.cancel -text "Cancel" -command {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
|
|
bind .sz <Escape> {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
|
|
wm protocol .sz WM_DELETE_WINDOW {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
|
|
button .sz.done -text "Done" -command {destroy .sz}
|
|
|
|
pack .sz.l1 .sz.l2 .sz.l3 \
|
|
.sz.g0 .sz.g1 .sz.g2 .sz.g3 .sz.g4 .sz.g5 .sz.g6 .sz.g7 \
|
|
.sz.c \
|
|
.sz.d0 .sz.d1 .sz.d2 .sz.d3 \
|
|
.sz.cancel .sz.done -side top -fill x
|
|
|
|
center_win .sz
|
|
focus .sz.c.e
|
|
}
|
|
|
|
proc choose_xserver_dialog {} {
|
|
toplev .st
|
|
wm title .st "X Server Type"
|
|
global ts_xserver_type choose_xserver
|
|
|
|
set def "Xvfb"
|
|
global ts_xserver_type_def
|
|
if {$ts_xserver_type_def != ""} {
|
|
set def $ts_xserver_type_def
|
|
}
|
|
|
|
if {$ts_xserver_type == ""} {
|
|
set ts_xserver_type $def
|
|
}
|
|
|
|
label .st.l1 -anchor w -text "Select the type of remote X server"
|
|
label .st.l2 -anchor w -text "for your session (default: $def)"
|
|
|
|
radiobutton .st.b1 -anchor w -variable ts_xserver_type -value Xvfb -text "Xvfb"
|
|
|
|
radiobutton .st.b2 -anchor w -variable ts_xserver_type -value Xdummy -text "Xdummy"
|
|
|
|
radiobutton .st.b3 -anchor w -variable ts_xserver_type -value Xvnc -text "Xvnc"
|
|
|
|
radiobutton .st.b4 -anchor w -variable ts_xserver_type -value Xvnc.redirect -text "Xvnc.redirect"
|
|
|
|
button .st.cancel -text "Cancel" -command {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
|
|
bind .st <Escape> {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
|
|
wm protocol .st WM_DELETE_WINDOW {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
|
|
button .st.done -text "Done" -command {destroy .st}
|
|
|
|
pack .st.l1 .st.l2 .st.b1 .st.b2 .st.b3 .st.b4 .st.cancel .st.done -side top -fill x
|
|
|
|
center_win .st
|
|
}
|
|
|
|
proc set_ts_options {} {
|
|
global use_cups use_sound use_smbmnt
|
|
global change_vncviewer choose_xserver
|
|
global ts_only is_windows
|
|
global darwin_cotvnc use_x11_macosx uname
|
|
if {! $ts_only} {
|
|
return
|
|
}
|
|
catch {destroy .o}
|
|
toplev .ot
|
|
wm title .ot "Options"
|
|
|
|
set i 1
|
|
|
|
checkbutton .ot.b$i -anchor w -variable choose_desktop -text \
|
|
"Desktop Type" \
|
|
-command {if {$choose_desktop} {choose_desktop_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable choose_desktop_geom -text \
|
|
"Desktop Size" \
|
|
-command {if {$choose_desktop_geom} {choose_size_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable choose_xserver -text \
|
|
"X Server Type" \
|
|
-command {if {$choose_xserver} {choose_xserver_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable use_cups -text \
|
|
"Enable Printing" \
|
|
-command {if {$use_cups} {cups_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable use_sound -text \
|
|
"Enable Sound" \
|
|
-command {if {$use_sound} {sound_dialog}}
|
|
incr i
|
|
|
|
# checkbutton .ot.b$i -anchor w -variable use_smbmnt -text \
|
|
# "Enable SMB mount tunnelling" \
|
|
# -command {if {$use_smbmnt} {smb_dialog}}
|
|
# incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable choose_filexfer -text \
|
|
"File Transfer" \
|
|
-command {if {$choose_filexfer} {ts_filexfer_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable use_viewonly -text \
|
|
"View Only"
|
|
incr i
|
|
|
|
checkbutton .ot.b$i -anchor w -variable change_vncviewer -text \
|
|
"Change VNC Viewer" \
|
|
-command change_vncviewer_dialog_wrap
|
|
incr i
|
|
|
|
if {!$is_windows && $uname == "Darwin"} {
|
|
checkbutton .ot.b$i -anchor w -variable use_x11_macosx -text \
|
|
"X11 viewer MacOSX" \
|
|
-command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons}
|
|
incr i
|
|
}
|
|
|
|
button .ot.b$i -anchor w -text " Delete Profile..." \
|
|
-command {destroy .ot; delete_profile}
|
|
incr i
|
|
|
|
button .ot.b$i -anchor w -text " Advanced ..." -command {set_ts_adv_options}
|
|
incr i
|
|
|
|
for {set j 1} {$j < $i} {incr j} {
|
|
pack .ot.b$j -side top -fill x
|
|
}
|
|
|
|
frame .ot.b
|
|
button .ot.b.done -text "Done" -command {destroy .ot}
|
|
button .ot.b.help -text "Help" -command help_ts_opts
|
|
pack .ot.b.help .ot.b.done -fill x -expand 1 -side left
|
|
|
|
bind .ot <Escape> {destroy .ot}
|
|
wm protocol .ot WM_DELETE_WINDOW {destroy .ot}
|
|
|
|
pack .ot.b -side top -fill x
|
|
|
|
center_win .ot
|
|
wm resizable .ot 1 0
|
|
focus .ot
|
|
}
|
|
|
|
proc set_ts_adv_options {} {
|
|
global ts_only ts_unixpw ts_vncshared
|
|
global ts_ncache ts_multisession
|
|
global choose_othervnc darwin_cotvnc choose_sleep
|
|
global is_windows
|
|
|
|
if {! $ts_only} {
|
|
return
|
|
}
|
|
catch {destroy .ot}
|
|
toplev .ot2
|
|
wm title .ot2 "Advanced"
|
|
|
|
set i 1
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable ts_vncshared -text \
|
|
"VNC Shared" \
|
|
-command {if {$ts_vncshared} {ts_vncshared_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable choose_multisession -text \
|
|
"Multiple Sessions" \
|
|
-command {if {$choose_multisession} {ts_multi_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable ts_xlogin -text \
|
|
"X Login Greeter" \
|
|
-command {if {$ts_xlogin} {ts_xlogin_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable choose_othervnc -text \
|
|
"Other VNC Server" \
|
|
-command {if {$choose_othervnc} {ts_othervnc_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable ts_unixpw -text \
|
|
"Use unixpw" \
|
|
-command {if {$ts_unixpw} {ts_unixpw_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable use_bgr233 -text \
|
|
"Client 8bit Color"
|
|
if {$darwin_cotvnc} {.ot2.b$i configure -state disabled}
|
|
global darwin_cotvnc_blist
|
|
set darwin_cotvnc_blist(.ot2.b$i) 1
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable choose_ncache -text \
|
|
"Client-Side Caching" \
|
|
-command {if {$choose_ncache} {ts_ncache_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable choose_x11vnc_opts -text \
|
|
"X11VNC Options" \
|
|
-command {if {$choose_x11vnc_opts} {ts_x11vnc_opts_dialog}}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable choose_sleep -text \
|
|
"Extra Sleep" \
|
|
-command {if {$choose_sleep} {ts_sleep_dialog}}
|
|
incr i
|
|
|
|
if {$is_windows} {
|
|
checkbutton .ot2.b$i -anchor w -variable choose_parg -text \
|
|
"Putty Args" \
|
|
-command {if {$choose_parg} {ts_putty_args_dialog}}
|
|
incr i
|
|
}
|
|
|
|
if {!$is_windows} {
|
|
checkbutton .ot2.b$i -anchor w -variable ssh_local_protection -text \
|
|
"SSH Local Protections" \
|
|
-command {if {$ssh_local_protection} {ssh_sec_dialog}}
|
|
if {$is_windows} {.ot2.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton .ot2.b$i -anchor w -variable ssh_known_hosts -text \
|
|
"SSH KnownHosts file" \
|
|
-command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}}
|
|
if {$is_windows} {.ot2.b$i configure -state disabled}
|
|
incr i
|
|
}
|
|
|
|
if {$is_windows} {
|
|
button .ot2.b$i -anchor w -text " Putty Agent" \
|
|
-command {catch {exec pageant.exe &}}
|
|
incr i
|
|
|
|
button .ot2.b$i -anchor w -text " Putty Key-Gen" \
|
|
-command {catch {exec puttygen.exe &}}
|
|
incr i
|
|
}
|
|
|
|
global env
|
|
if {![info exists env(SSVNC_TS_ALWAYS)]} {
|
|
button .ot2.b$i -anchor w -text " SSVNC Mode" \
|
|
-command {destroy .ot2; to_ssvnc}
|
|
incr i
|
|
}
|
|
|
|
if {!$is_windows} {
|
|
button .ot2.b$i -anchor w -text " Unix ssvncviewer ..." \
|
|
-command {set_ssvncviewer_options}
|
|
if {$is_windows} {
|
|
.ot2.b$i configure -state disabled
|
|
}
|
|
global change_vncviewer
|
|
if {$change_vncviewer} {
|
|
.ot2.b$i configure -state disabled
|
|
}
|
|
global ts_uss_button
|
|
set ts_uss_button .ot2.b$i
|
|
incr i
|
|
}
|
|
|
|
for {set j 1} {$j < $i} {incr j} {
|
|
pack .ot2.b$j -side top -fill x
|
|
}
|
|
|
|
frame .ot2.b
|
|
button .ot2.b.done -text "Done" -command {destroy .ot2}
|
|
button .ot2.b.help -text "Help" -command help_ts_opts
|
|
pack .ot2.b.help .ot2.b.done -fill x -expand 1 -side left
|
|
|
|
bind .ot2 <Escape> {destroy .ot2}
|
|
wm protocol .ot2 WM_DELETE_WINDOW {destroy .ot2}
|
|
|
|
pack .ot2.b -side top -fill x
|
|
|
|
center_win .ot2
|
|
wm resizable .ot2 1 0
|
|
focus .ot2
|
|
}
|
|
|
|
proc change_vncviewer_dialog_wrap {} {
|
|
global change_vncviewer ts_uss_button is_windows
|
|
if {$change_vncviewer} {
|
|
change_vncviewer_dialog
|
|
catch {tkwait window .chviewer}
|
|
}
|
|
if {$change_vncviewer || $is_windows} {
|
|
catch {.oa.ss configure -state disabled}
|
|
} else {
|
|
catch {.oa.ss configure -state normal}
|
|
}
|
|
if [info exists ts_uss_button] {
|
|
if {$change_vncviewer || $is_windows} {
|
|
catch {$ts_uss_button configure -state disabled}
|
|
} else {
|
|
catch {$ts_uss_button configure -state normal}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc set_advanced_options {} {
|
|
global use_cups use_sound use_smbmnt
|
|
global change_vncviewer
|
|
global use_port_knocking port_knocking_list
|
|
global is_windows darwin_cotvnc
|
|
global use_ssh use_sshssl
|
|
global use_x11_macosx
|
|
global adv_ssh
|
|
global showing_no_encryption
|
|
global x11vnc_xlogin_widget
|
|
|
|
catch {destroy .o}
|
|
toplev .oa
|
|
wm title .oa "Advanced Options"
|
|
|
|
set i 1
|
|
|
|
checkbutton .oa.b$i -anchor w -variable use_cups -text \
|
|
"Enable CUPS Print tunnelling" \
|
|
-command {if {$use_cups} {cups_dialog}}
|
|
if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
|
|
set adv_ssh(cups) .oa.b$i
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable use_sound -text \
|
|
"Enable ESD/ARTSD Audio tunnelling" \
|
|
-command {if {$use_sound} {sound_dialog}}
|
|
if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
|
|
set adv_ssh(snd) .oa.b$i
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable use_smbmnt -text \
|
|
"Enable SMB mount tunnelling" \
|
|
-command {if {$use_smbmnt} {smb_dialog}}
|
|
if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
|
|
set adv_ssh(smb) .oa.b$i
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable use_x11vnc_xlogin -text \
|
|
"Automatically Find X Login/Greeter" -command {x11vnc_find_adjust "xlogin"}
|
|
if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
|
|
set x11vnc_xlogin_widget ".oa.b$i"
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable additional_port_redirs -text \
|
|
"Additional Port Redirs (via SSH)" \
|
|
-command {if {$additional_port_redirs} {port_redir_dialog}}
|
|
if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
|
|
set adv_ssh(redirs) .oa.b$i
|
|
incr i
|
|
|
|
global use_ssl use_ssh use_sshssl
|
|
|
|
if {!$is_windows} {
|
|
checkbutton .oa.b$i -anchor w -variable ssh_known_hosts -text \
|
|
"Private SSH KnownHosts file" \
|
|
-command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}}
|
|
set adv_ssh(knownhosts) .oa.b$i
|
|
if {$use_ssl} {.oa.b$i configure -state disabled}
|
|
if {$is_windows} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable ssh_local_protection -text \
|
|
"SSH Local Port Protections" \
|
|
-command {if {$ssh_local_protection} {ssh_sec_dialog}}
|
|
global ssh_local_protection_button
|
|
set ssh_local_protection_button .oa.b$i
|
|
if {$use_ssl} {.oa.b$i configure -state disabled}
|
|
if {$is_windows} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
}
|
|
|
|
global ssh_only
|
|
if {!$ssh_only} {
|
|
if {!$is_windows} {
|
|
checkbutton .oa.b$i -anchor w -variable stunnel_local_protection -text \
|
|
"STUNNEL Local Port Protections" \
|
|
-command {if {$stunnel_local_protection} {stunnel_sec_dialog}}
|
|
global stunnel_local_protection_button
|
|
set stunnel_local_protection_button .oa.b$i
|
|
if {$use_ssh} {.oa.b$i configure -state disabled}
|
|
if {$is_windows} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
}
|
|
|
|
checkbutton .oa.b$i -anchor w -variable disable_ssl_workarounds -text \
|
|
"Disable SSL Workarounds" \
|
|
-command {if {$disable_ssl_workarounds} {disable_ssl_workarounds_dialog}}
|
|
global disable_ssl_workarounds_button
|
|
set disable_ssl_workarounds_button .oa.b$i
|
|
if {$use_ssh} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
|
|
if {!$is_windows} {
|
|
checkbutton .oa.b$i -anchor w -variable ultra_dsm -text \
|
|
"UltraVNC DSM Encryption Plugin" \
|
|
-command {if {$ultra_dsm} {ultra_dsm_dialog}}
|
|
global ultra_dsm_button
|
|
set ultra_dsm_button .oa.b$i
|
|
if {$is_windows} {.oa.b$i configure -state disabled}
|
|
if {$use_ssh} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
}
|
|
|
|
checkbutton .oa.b$i -anchor w -variable no_probe_vencrypt -text \
|
|
"Do not Probe for VeNCrypt"
|
|
global no_probe_vencrypt_button
|
|
set no_probe_vencrypt_button .oa.b$i
|
|
if {$use_ssh} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable server_vencrypt -text \
|
|
"Server uses VeNCrypt SSL encryption"
|
|
global vencrypt_button
|
|
set vencrypt_button .oa.b$i
|
|
if {$use_ssh} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable server_anondh -text \
|
|
"Server uses Anonymous Diffie-Hellman" -command no_certs_tutorial_mesg
|
|
global anondh_button
|
|
set anondh_button .oa.b$i
|
|
if {$use_ssh} {.oa.b$i configure -state disabled}
|
|
incr i
|
|
}
|
|
|
|
checkbutton .oa.b$i -anchor w -variable change_vncviewer -text \
|
|
"Change VNC Viewer" \
|
|
-command change_vncviewer_dialog_wrap
|
|
incr i
|
|
|
|
checkbutton .oa.b$i -anchor w -variable use_port_knocking -text \
|
|
"Port Knocking" \
|
|
-command {if {$use_port_knocking} {port_knocking_dialog}}
|
|
incr i
|
|
|
|
for {set j 1} {$j < $i} {incr j} {
|
|
pack .oa.b$j -side top -fill x
|
|
}
|
|
|
|
global include_list extra_sleep
|
|
frame .oa.fis
|
|
frame .oa.fis.fL
|
|
frame .oa.fis.fR
|
|
label .oa.fis.fL.la -anchor w -text "Include:"
|
|
label .oa.fis.fL.lb -anchor w -text "Sleep:"
|
|
if {$is_windows} {
|
|
label .oa.fis.fL.lc -anchor w -text "Putty Args:"
|
|
pack .oa.fis.fL.la .oa.fis.fL.lb .oa.fis.fL.lc -side top -fill x
|
|
} else {
|
|
pack .oa.fis.fL.la .oa.fis.fL.lb -side top -fill x
|
|
}
|
|
|
|
entry .oa.fis.fR.ea -width 10 -textvariable include_list
|
|
entry .oa.fis.fR.eb -width 10 -textvariable extra_sleep
|
|
if {$is_windows} {
|
|
entry .oa.fis.fR.ec -width 10 -textvariable putty_args
|
|
pack .oa.fis.fR.ea .oa.fis.fR.eb .oa.fis.fR.ec -side top -fill x
|
|
} else {
|
|
pack .oa.fis.fR.ea .oa.fis.fR.eb -side top -fill x
|
|
}
|
|
|
|
pack .oa.fis.fL -side left
|
|
pack .oa.fis.fR -side right -expand 1 -fill x
|
|
|
|
pack .oa.fis -side top -fill x
|
|
|
|
|
|
if {!$is_windows} {
|
|
global uname
|
|
set t1 " Unix ssvncviewer ..."
|
|
if {$uname == "Darwin" } { regsub {^ *} $t1 "" t1 }
|
|
button .oa.ss -anchor w -text $t1 -command set_ssvncviewer_options
|
|
pack .oa.ss -side top -fill x
|
|
if {$is_windows} {
|
|
.oa.ss configure -state disabled
|
|
}
|
|
global change_vncviewer
|
|
if {$change_vncviewer} {
|
|
.oa.ss configure -state disabled
|
|
}
|
|
|
|
set t2 " Use ssh-agent"
|
|
if {$uname == "Darwin" } { regsub {^ *} $t2 "" t2 }
|
|
|
|
button .oa.sa -anchor w -text $t2 -command ssh_agent_restart
|
|
pack .oa.sa -side top -fill x
|
|
if {$is_windows} {
|
|
.oa.sa configure -state disabled
|
|
}
|
|
} else {
|
|
set t1 " Launch Putty Agent"
|
|
button .oa.pa -anchor w -text $t1 -command {catch {exec pageant.exe &}}
|
|
pack .oa.pa -side top -fill x
|
|
|
|
set t2 " Launch Putty Key-Gen"
|
|
button .oa.pg -anchor w -text $t2 -command {catch {exec puttygen.exe &}}
|
|
pack .oa.pg -side top -fill x
|
|
}
|
|
|
|
frame .oa.b
|
|
button .oa.b.done -text "Done" -command {destroy .oa}
|
|
bind .oa <Escape> {destroy .oa}
|
|
wm protocol .oa WM_DELETE_WINDOW {destroy .oa}
|
|
button .oa.b.help -text "Help" -command help_advanced_opts
|
|
|
|
global use_listen
|
|
if {$use_listen} {
|
|
button .oa.b.connect -text "Listen" -command launch
|
|
} else {
|
|
button .oa.b.connect -text "Connect" -command launch
|
|
}
|
|
|
|
pack .oa.b.help .oa.b.connect .oa.b.done -fill x -expand 1 -side left
|
|
|
|
pack .oa.b -side top -fill x
|
|
|
|
center_win .oa
|
|
wm resizable .oa 1 0
|
|
focus .oa
|
|
}
|
|
|
|
proc set_ssvncviewer_options {} {
|
|
global is_windows darwin_cotvnc
|
|
global use_ssh use_sshssl use_x11cursor use_rawlocal use_notty use_popupfix use_alpha use_turbovnc disable_pipeline use_grab use_nobell
|
|
global use_send_clipboard use_send_always
|
|
global ssvnc_scale ssvnc_escape
|
|
global server_vencrypt server_anondh
|
|
|
|
if {$is_windows} {
|
|
return
|
|
}
|
|
|
|
catch {destroy .oa}
|
|
toplev .os
|
|
wm title .os "Unix ssvncviewer Options"
|
|
|
|
set darwinlist [list]
|
|
|
|
set f0 .os.f
|
|
frame $f0
|
|
set fl $f0.fl
|
|
frame $fl
|
|
set fr $f0.fr
|
|
frame $fr
|
|
|
|
set i 1
|
|
set j 1
|
|
|
|
checkbutton $fl.b$i -anchor w -variable multiple_listen -text \
|
|
"Multiple LISTEN Connections" \
|
|
-command {if {$multiple_listen} {multilisten_dialog}}
|
|
global multiple_listen_button use_listen
|
|
set multiple_listen_button $fl.b$i
|
|
if {$is_windows} {$fl.b$i configure -state disabled}
|
|
if {!$use_listen} {$fl.b$i configure -state disabled}
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable listen_once -text \
|
|
"Listen Once"
|
|
global listen_once_button
|
|
set listen_once_button $fl.b$i
|
|
if {!$use_listen} {$fl.b$i configure -state disabled}
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable listen_accept_popup -text \
|
|
"Listen Accept Popup Dialog" \
|
|
-command { if {$listen_accept_popup} { catch {$listen_accept_popup_button_sc configure -state normal} } else { catch {$listen_accept_popup_button_sc configure -state disabled} } }
|
|
global listen_accept_popup_button
|
|
set listen_accept_popup_button $fl.b$i
|
|
if {!$use_listen} {$fl.b$i configure -state disabled}
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
global listen_accept_popup
|
|
checkbutton $fl.b$i -anchor w -variable listen_accept_popup_sc -text \
|
|
" Accept Popup UltraVNC Single Click"
|
|
global listen_accept_popup_button_sc
|
|
set listen_accept_popup_button_sc $fl.b$i
|
|
if {!$use_listen} {$fl.b$i configure -state disabled}
|
|
if {!$listen_accept_popup} {$fl.b$i configure -state disabled}
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_x11cursor -text \
|
|
"Use X11 Cursor"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_nobell -text \
|
|
"Disable Bell"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_rawlocal -text \
|
|
"Use Raw Local"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_notty -text \
|
|
"Avoid Using Terminal"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_popupfix -text \
|
|
"Use Popup Fix"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_grab -text \
|
|
"Use XGrabServer (for fullscreen)" \
|
|
-command {if {$use_grab} {use_grab_dialog}}
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_alpha -text \
|
|
"Cursor Alphablending (32bpp required) "
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_turbovnc -text \
|
|
"TurboVNC (if available on platform)"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable disable_pipeline -text \
|
|
"Disable Pipelined Updates"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_send_clipboard -text \
|
|
"Send CLIPBOARD not PRIMARY"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
checkbutton $fl.b$i -anchor w -variable use_send_always -text \
|
|
"Send Selection Every time"
|
|
lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
|
|
incr i
|
|
|
|
set relief ridge
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
global ffont
|
|
label $fr.b$j.l -font $ffont -anchor w -text "Examples: '0.75', '1024x768', 'fit' (fill screen), or 'auto' ";
|
|
|
|
global ssvnc_scale
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "Scaling: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable ssvnc_scale
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
label $fr.b$j.l -font $ffont -anchor w -text "Examples: 'default', 'Control_L,Alt_L', 'never'";
|
|
|
|
global ssvnc_escape
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "Escape Keys: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable ssvnc_escape
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
button $fr.b$j.f.b -relief ridge -text Help -command ssvnc_escape_help
|
|
lappend darwinlist $fr.b$j.f.b; if {$darwin_cotvnc} {$fr.b$j.f.b configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.b -side right
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
label $fr.b$j.l -font $ffont -anchor w -text "Enter the max height in pixels, e.g. '900'";
|
|
|
|
global ycrop_string
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "Y Crop: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable ycrop_string
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
label $fr.b$j.l -font $ffont -anchor w -text "Enter the scrollbar width in pixels, e.g. '4'";
|
|
|
|
global sbwid_string
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "ScrollBar Width: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable sbwid_string
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
label $fr.b$j.l -font $ffont -anchor w -text "Enter the RFB version to pretend to be using, e.g. '3.4'";
|
|
label $fr.b$j.l2 -font $ffont -anchor w -text "Sometimes needed for UltraVNC: 3.4, 3.6, 3.14, 3.16";
|
|
|
|
global rfbversion
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "RFB Version: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable rfbversion
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l $fr.b$j.l2 -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
label $fr.b$j.l1 -font $ffont -anchor w -text "List encodings in preferred order, for example";
|
|
label $fr.b$j.l2 -font $ffont -anchor w -text "'copyrect zrle tight' The full list of encodings is:";
|
|
label $fr.b$j.l3 -font $ffont -anchor w -text "copyrect tight zrle zywrle hextile zlib corre rre raw";
|
|
|
|
global ssvnc_encodings
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "Encodings: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable ssvnc_encodings
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 $fr.b$j.l3 -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
frame $fr.b$j -relief $relief -borderwidth 2
|
|
|
|
label $fr.b$j.l1 -font $ffont -anchor w -text "Add any extra options for ssvncviewer that you want.";
|
|
label $fr.b$j.l2 -font $ffont -anchor w -text "For example: -16bpp -appshare -noshm etc. See Help for a list.";
|
|
|
|
global ssvnc_extra_opts
|
|
frame $fr.b$j.f
|
|
label $fr.b$j.f.l -text "Extra Options: "
|
|
lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
|
|
entry $fr.b$j.f.e -width 10 -textvariable ssvnc_extra_opts
|
|
lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
|
|
pack $fr.b$j.f.l -side left
|
|
pack $fr.b$j.f.e -side right -expand 1 -fill x
|
|
|
|
pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 -side top -fill x
|
|
|
|
incr j
|
|
|
|
frame $fr.b$j -height 2; incr j
|
|
|
|
for {set k 1} {$k < $i} {incr k} {
|
|
pack $fl.b$k -side top -fill x
|
|
}
|
|
for {set k 1} {$k < $j} {incr k} {
|
|
pack $fr.b$k -side top -fill x
|
|
}
|
|
|
|
pack $fl -side left -fill both
|
|
pack $fr -side left -fill both -expand 1
|
|
|
|
pack $f0 -side top -fill both
|
|
|
|
frame .os.b
|
|
button .os.b.done -text "Done" -command {destroy .os}
|
|
bind .os <Escape> {destroy .os}
|
|
wm protocol .os WM_DELETE_WINDOW {destroy .os}
|
|
button .os.b.help -text "Help" -command help_ssvncviewer_opts
|
|
|
|
global use_listen
|
|
if {$use_listen} {
|
|
button .os.b.connect -text "Listen" -command launch
|
|
} else {
|
|
button .os.b.connect -text "Connect" -command launch
|
|
}
|
|
|
|
pack .os.b.help .os.b.connect .os.b.done -fill x -expand 1 -side left
|
|
|
|
pack .os.b -side top -fill x
|
|
|
|
global darwin_cotvnc_blist
|
|
foreach b $darwinlist {
|
|
set darwin_cotvnc_blist($b) 1
|
|
}
|
|
|
|
center_win .os
|
|
wm resizable .os 1 0
|
|
wm minsize .os [winfo reqwidth .os] [winfo reqheight .os]
|
|
focus .os
|
|
}
|
|
|
|
|
|
proc in_path {cmd} {
|
|
global env
|
|
set p $env(PATH)
|
|
foreach dir [split $p ":"] {
|
|
set try "$dir/$cmd"
|
|
if [file exists $try] {
|
|
return "$try"
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
proc ssh_agent_restart {} {
|
|
global env
|
|
|
|
set got_ssh_agent 0
|
|
set got_ssh_add 0
|
|
set got_ssh_agent2 0
|
|
set got_ssh_add2 0
|
|
|
|
if {[in_path "ssh-agent"] != ""} {set got_ssh_agent 1}
|
|
if {[in_path "ssh-agent2"] != ""} {set got_ssh_agent2 1}
|
|
if {[in_path "ssh-add"] != ""} {set got_ssh_add 1}
|
|
if {[in_path "ssh-add2"] != ""} {set got_ssh_add2 1}
|
|
|
|
set ssh_agent ""
|
|
set ssh_add ""
|
|
if {[info exists env(USER)] && $env(USER) == "runge"} {
|
|
if {$got_ssh_agent2} {
|
|
set ssh_agent "ssh-agent2"
|
|
}
|
|
if {$got_ssh_add2} {
|
|
set ssh_add "ssh-add2"
|
|
}
|
|
}
|
|
if {$ssh_agent == "" && $got_ssh_agent} {
|
|
set ssh_agent "ssh-agent"
|
|
}
|
|
if {$ssh_add == "" && $got_ssh_add} {
|
|
set ssh_add "ssh-add"
|
|
}
|
|
if {$ssh_agent == ""} {
|
|
bell
|
|
mesg "could not find ssh-agent in PATH"
|
|
return
|
|
}
|
|
if {$ssh_add == ""} {
|
|
bell
|
|
mesg "could not find ssh-add in PATH"
|
|
return
|
|
}
|
|
set tmp $env(SSVNC_HOME)/.vnc-sa[tpid]
|
|
set tmp [mytmp $tmp]
|
|
set fh ""
|
|
catch {set fh [open $tmp "w"]}
|
|
if {$fh == ""} {
|
|
bell
|
|
mesg "could not open tmp file $tmp"
|
|
return
|
|
}
|
|
|
|
puts $fh "#!/bin/sh"
|
|
puts $fh "eval `$ssh_agent -s`"
|
|
puts $fh "$ssh_add"
|
|
puts $fh "SSVNC_GUI_CHILD=\"\""
|
|
puts $fh "export SSVNC_GUI_CHILD"
|
|
|
|
global buck_zero
|
|
set cmd $buck_zero
|
|
|
|
if [info exists env(SSVNC_GUI_CMD)] {
|
|
set cmd $env(SSVNC_GUI_CMD)
|
|
}
|
|
#puts $fh "$cmd </dev/null 1>/dev/null 2>/dev/null &"
|
|
puts $fh "nohup $cmd &"
|
|
puts $fh "sleep 1"
|
|
puts $fh "rm -f $tmp"
|
|
close $fh
|
|
|
|
wm withdraw .
|
|
catch {wm withdraw .o}
|
|
catch {wm withdraw .oa}
|
|
|
|
unix_terminal_cmd "+200+200" "Restarting with ssh-agent/ssh-add" "sh $tmp" 1
|
|
after 10000
|
|
destroy .
|
|
exit
|
|
}
|
|
|
|
proc putty_pw_entry {mode} {
|
|
if {$mode == "check"} {
|
|
global use_sshssl use_ssh
|
|
if {$use_sshssl || $use_ssh} {
|
|
putty_pw_entry enable
|
|
} else {
|
|
putty_pw_entry disable
|
|
}
|
|
return
|
|
}
|
|
if {$mode == "disable"} {
|
|
catch {.o.pw.l configure -state disabled}
|
|
catch {.o.pw.e configure -state disabled}
|
|
} else {
|
|
catch {.o.pw.l configure -state normal}
|
|
catch {.o.pw.e configure -state normal}
|
|
}
|
|
}
|
|
proc adv_ssh_tog {on} {
|
|
global adv_ssh
|
|
foreach b {cups snd smb redirs knownhosts} {
|
|
if [info exists adv_ssh($b)] {
|
|
if {$on} {
|
|
catch {$adv_ssh($b) configure -state normal}
|
|
} else {
|
|
catch {$adv_ssh($b) configure -state disabled}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc adv_listen_ssl_tog {on} {
|
|
global stunnel_local_protection_button is_windows
|
|
global disable_ssl_workarounds_button
|
|
global vencrypt_button no_probe_vencrypt_button anondh_button ultra_dsm_button
|
|
|
|
set blist [list]
|
|
if [info exists stunnel_local_protection_button] {
|
|
lappend blist $stunnel_local_protection_button
|
|
}
|
|
if [info exists disable_ssl_workarounds_button] {
|
|
lappend blist $disable_ssl_workarounds_button
|
|
}
|
|
if [info exists ultra_dsm_button] {
|
|
lappend blist $ultra_dsm_button
|
|
}
|
|
if [info exists no_probe_vencrypt_button] {
|
|
lappend blist $no_probe_vencrypt_button
|
|
}
|
|
if [info exists vencrypt_button] {
|
|
lappend blist $vencrypt_button
|
|
}
|
|
if [info exists anondh_button] {
|
|
lappend blist $anondh_button
|
|
}
|
|
foreach b $blist {
|
|
if {$on} {
|
|
catch {$b configure -state normal}
|
|
} else {
|
|
catch {$b configure -state disabled}
|
|
}
|
|
}
|
|
|
|
if {$is_windows} {
|
|
catch {$stunnel_local_protection_button configure -state disabled}
|
|
catch {$ultra_dsm_button configure -state disabled}
|
|
}
|
|
}
|
|
|
|
proc adv_listen_ssh_tog {on} {
|
|
global ssh_local_protection_button is_windows
|
|
if [info exists ssh_local_protection_button] {
|
|
if {$on} {
|
|
catch {$ssh_local_protection_button configure -state normal}
|
|
} else {
|
|
catch {$ssh_local_protection_button configure -state disabled}
|
|
}
|
|
}
|
|
if {$is_windows} {
|
|
catch {$ssh_local_protection_button configure -state disabled}
|
|
}
|
|
}
|
|
|
|
proc ssl_ssh_adjust {which} {
|
|
global use_ssl use_ssh use_sshssl sshssl_sw
|
|
global remote_ssh_cmd_list
|
|
global x11vnc_find_widget x11vnc_xlogin_widget uvnc_bug_widget
|
|
|
|
if {$which == "ssl"} {
|
|
set use_ssl 1
|
|
set use_ssh 0
|
|
set use_sshssl 0
|
|
set sshssl_sw "ssl"
|
|
catch {.f4.getcert configure -state normal}
|
|
catch {.f4.always configure -state normal}
|
|
if [info exists x11vnc_find_widget] {
|
|
catch {$x11vnc_find_widget configure -state disabled}
|
|
}
|
|
if [info exists x11vnc_xlogin_widget] {
|
|
catch {$x11vnc_xlogin_widget configure -state disabled}
|
|
}
|
|
if [info exists uvnc_bug_widget] {
|
|
catch {$uvnc_bug_widget configure -state normal}
|
|
}
|
|
adv_ssh_tog 0
|
|
adv_listen_ssl_tog 1
|
|
adv_listen_ssh_tog 0
|
|
} elseif {$which == "none"} {
|
|
set use_ssl 0
|
|
set use_ssh 0
|
|
set use_sshssl 0
|
|
set sshssl_sw "none"
|
|
catch {.f4.getcert configure -state disabled}
|
|
catch {.f4.always configure -state disabled}
|
|
if [info exists x11vnc_find_widget] {
|
|
catch {$x11vnc_find_widget configure -state disabled}
|
|
}
|
|
if [info exists x11vnc_xlogin_widget] {
|
|
catch {$x11vnc_xlogin_widget configure -state disabled}
|
|
}
|
|
if [info exists uvnc_bug_widget] {
|
|
catch {$uvnc_bug_widget configure -state normal}
|
|
}
|
|
adv_ssh_tog 0
|
|
adv_listen_ssl_tog 0
|
|
adv_listen_ssh_tog 0
|
|
} elseif {$which == "ssh"} {
|
|
set use_ssl 0
|
|
set use_ssh 1
|
|
set use_sshssl 0
|
|
set sshssl_sw "ssh"
|
|
catch {.f4.getcert configure -state disabled}
|
|
catch {.f4.always configure -state disabled}
|
|
if [info exists x11vnc_find_widget] {
|
|
catch {$x11vnc_find_widget configure -state normal}
|
|
}
|
|
if [info exists x11vnc_xlogin_widget] {
|
|
catch {$x11vnc_xlogin_widget configure -state normal}
|
|
}
|
|
if [info exists uvnc_bug_widget] {
|
|
catch {$uvnc_bug_widget configure -state disabled}
|
|
}
|
|
adv_ssh_tog 1
|
|
adv_listen_ssl_tog 0
|
|
adv_listen_ssh_tog 1
|
|
} elseif {$which == "sshssl"} {
|
|
set use_ssl 0
|
|
set use_ssh 0
|
|
set use_sshssl 1
|
|
set sshssl_sw "sshssl"
|
|
catch {.f4.getcert configure -state disabled}
|
|
catch {.f4.always configure -state disabled}
|
|
if [info exists x11vnc_find_widget] {
|
|
catch {$x11vnc_find_widget configure -state normal}
|
|
}
|
|
if [info exists x11vnc_xlogin_widget] {
|
|
catch {$x11vnc_xlogin_widget configure -state normal}
|
|
}
|
|
if [info exists uvnc_bug_widget] {
|
|
catch {$uvnc_bug_widget configure -state normal}
|
|
}
|
|
adv_ssh_tog 1
|
|
adv_listen_ssl_tog 1
|
|
adv_listen_ssh_tog 1
|
|
}
|
|
|
|
if [info exists remote_ssh_cmd_list] {
|
|
if {$use_ssh || $use_sshssl} {
|
|
foreach w $remote_ssh_cmd_list {
|
|
$w configure -state normal
|
|
}
|
|
}
|
|
if {$use_ssl || $sshssl_sw == "none"} {
|
|
foreach w $remote_ssh_cmd_list {
|
|
$w configure -state disabled
|
|
}
|
|
}
|
|
}
|
|
|
|
if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
|
|
if {$sshssl_sw != "none"} {
|
|
set use_ssl 1
|
|
set sshssl_sw "ssl"
|
|
}
|
|
}
|
|
global ssh_only ts_only
|
|
if {$ssh_only || $ts_only} {
|
|
set use_ssl 0
|
|
set use_sshssl 0
|
|
set use_ssh 1
|
|
set sshssl_sw "ssh"
|
|
}
|
|
|
|
putty_pw_entry check
|
|
}
|
|
|
|
proc listen_adjust {} {
|
|
global use_listen revs_button multiple_listen_button is_windows
|
|
global listen_once_button listen_accept_popup_button listen_accept_popup_button_sc
|
|
if {![info exists multiple_listen_button]} {
|
|
set multiple_listen_button "none"
|
|
}
|
|
if {$use_listen} {
|
|
catch {.b.conn configure -text "Listen"}
|
|
catch {.o.b.connect configure -text "Listen"}
|
|
catch {$multiple_listen_button configure -state normal}
|
|
catch {$listen_once_button configure -state normal}
|
|
catch {$listen_accept_popup_button configure -state normal}
|
|
catch {$listen_accept_popup_button_sc configure -state normal}
|
|
catch {mesg "Listen :N -> Port 5500+N, i.e. :0 -> 5500, :1 -> 5501, :2 -> 5502 ..."}
|
|
} else {
|
|
catch {.b.conn configure -text "Connect"}
|
|
catch {.o.b.connect configure -text "Connect"}
|
|
catch {$multiple_listen_button configure -state disabled}
|
|
catch {$listen_once_button configure -state disabled}
|
|
catch {$listen_accept_popup_button configure -state disabled}
|
|
catch {$listen_accept_popup_button_sc configure -state disabled}
|
|
catch {mesg "Switched to Forward Connection mode."}
|
|
}
|
|
if {$is_windows} {
|
|
catch {$multiple_listen_button configure -state disabled}
|
|
catch {$listen_once_button configure -state disabled}
|
|
catch {$listen_accept_popup_button configure -state disabled}
|
|
catch {$listen_accept_popup_button_sc configure -state disabled}
|
|
}
|
|
}
|
|
|
|
proc unixpw_adjust {} {
|
|
global is_windows use_unixpw darwin_cotvnc
|
|
if {$is_windows || $darwin_cotvnc} {
|
|
return;
|
|
}
|
|
if {$use_unixpw} {
|
|
pack configure .fu -after .f1 -fill x
|
|
catch {focus .fu.e}
|
|
} else {
|
|
pack forget .fu
|
|
}
|
|
}
|
|
|
|
proc x11vnc_find_adjust {which} {
|
|
global remote_ssh_cmd
|
|
global use_x11vnc_find x11vnc_find_widget
|
|
global use_x11vnc_xlogin x11vnc_xlogin_widget
|
|
|
|
if {$which == "find"} {
|
|
if {$use_x11vnc_find} {
|
|
set use_x11vnc_xlogin 0
|
|
}
|
|
} elseif {$which == "xlogin"} {
|
|
if {$use_x11vnc_xlogin} {
|
|
set use_x11vnc_find 0
|
|
}
|
|
}
|
|
if {! $use_x11vnc_find && ! $use_x11vnc_xlogin} {
|
|
set remote_ssh_cmd "";
|
|
return
|
|
}
|
|
if {![regexp {x11vnc} $remote_ssh_cmd]} {
|
|
set remote_ssh_cmd "";
|
|
}
|
|
regsub {^[ ]*PORT= [ ]*} $remote_ssh_cmd "" remote_ssh_cmd
|
|
regsub {^[ ]*P= [ ]*} $remote_ssh_cmd "" remote_ssh_cmd
|
|
regsub {^[ ]*sudo x11vnc[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
|
|
regsub {^[ ]*x11vnc[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
|
|
regsub -all {[ ]*-find[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
|
|
regsub -all {[ ]*-localhost[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
|
|
regsub -all {[ ]*-env FD_XDM=1[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
|
|
if {$use_x11vnc_find} {
|
|
set remote_ssh_cmd "PORT= x11vnc -find -localhost -nopw $remote_ssh_cmd"
|
|
} else {
|
|
set remote_ssh_cmd "PORT= sudo x11vnc -find -localhost -env FD_XDM=1 -nopw $remote_ssh_cmd"
|
|
}
|
|
regsub {[ ]*$} $remote_ssh_cmd "" remote_ssh_cmd
|
|
regsub {^[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
|
|
regsub -all {[ ][ ]*} $remote_ssh_cmd " " remote_ssh_cmd
|
|
}
|
|
|
|
proc set_darwin_cotvnc_buttons {} {
|
|
global darwin_cotvnc uname darwin_cotvnc_blist
|
|
|
|
if {$uname == "Darwin" && [info exists darwin_cotvnc_blist]} {
|
|
foreach b [array names darwin_cotvnc_blist] {
|
|
if {$darwin_cotvnc} {
|
|
catch {$b configure -state disabled}
|
|
} else {
|
|
catch {$b configure -state normal}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc disable_encryption {} {
|
|
global env
|
|
if {[info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} {
|
|
set s $env(SSVNC_DISABLE_ENCRYPTION_BUTTON)
|
|
if {$s != "" && $s != "0"} {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
proc set_options {} {
|
|
global use_alpha use_grab use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
|
|
global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
|
|
global use_send_clipboard use_send_always
|
|
global compresslevel_text quality_text
|
|
global env is_windows darwin_cotvnc uname
|
|
global use_listen
|
|
global use_x11vnc_find x11vnc_find_widget
|
|
global use_x11vnc_xlogin x11vnc_xlogin_widget uvnc_bug_widget
|
|
global ts_only
|
|
global darwin_cotvnc_blist
|
|
global showing_no_encryption no_enc_button no_enc_prev
|
|
|
|
if {$ts_only} {
|
|
set_ts_options
|
|
return
|
|
}
|
|
|
|
toplev .o
|
|
wm title .o "SSL/SSH VNC Options"
|
|
|
|
set i 1
|
|
|
|
radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssl -text \
|
|
"Use SSL" -command {ssl_ssh_adjust ssl}
|
|
incr i
|
|
|
|
radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssh -text \
|
|
"Use SSH" -command {ssl_ssh_adjust ssh}
|
|
incr i
|
|
|
|
radiobutton .o.b$i -anchor w -variable sshssl_sw -value sshssl -text \
|
|
"Use SSH+SSL" -command {ssl_ssh_adjust sshssl}
|
|
set iss $i
|
|
set no_enc_prev .o.b$i
|
|
incr i
|
|
|
|
radiobutton .o.b$i -anchor w -variable sshssl_sw -value none -text \
|
|
"No Encryption" -command {ssl_ssh_adjust none}
|
|
set no_enc_button .o.b$i
|
|
set ine $i
|
|
incr i
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_x11vnc_find -text \
|
|
"Automatically Find X Session" -command {x11vnc_find_adjust "find"}
|
|
if {!$use_ssh && !$use_sshssl} {.o.b$i configure -state disabled}
|
|
set x11vnc_find_widget ".o.b$i"
|
|
incr i
|
|
|
|
if {! $is_windows} {
|
|
checkbutton .o.b$i -anchor w -variable use_unixpw -text \
|
|
"Unix Username & Password" -command {unixpw_adjust}
|
|
if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
set darwin_cotvnc_blist(.o.b$i) 1
|
|
incr i
|
|
}
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_listen -text \
|
|
"Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"} else {set vncdisplay ""}; if {0 && $use_listen} {destroy .o}}
|
|
#if {$is_windows} {.o.b$i configure -state disabled}
|
|
#if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
#set darwin_cotvnc_blist(.o.b$i) 1
|
|
incr i
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_viewonly -text \
|
|
"View Only"
|
|
incr i
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_fullscreen -text \
|
|
"Fullscreen"
|
|
incr i
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_raise_on_beep -text \
|
|
"Raise On Beep"
|
|
if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
set darwin_cotvnc_blist(.o.b$i) 1
|
|
incr i
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_bgr233 -text \
|
|
"Use 8bit color (-bgr233)"
|
|
if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
set darwin_cotvnc_blist(.o.b$i) 1
|
|
incr i
|
|
|
|
checkbutton .o.b$i -anchor w -variable use_nojpeg -text \
|
|
"Do not use JPEG (-nojpeg)"
|
|
if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
set darwin_cotvnc_blist(.o.b$i) 1
|
|
incr i
|
|
|
|
if {$uname == "Darwin"} {
|
|
checkbutton .o.b$i -anchor w -variable use_x11_macosx -text \
|
|
"Use X11 vncviewer on MacOSX" \
|
|
-command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons}
|
|
if {$uname != "Darwin"} {.o.b$i configure -state disabled}
|
|
incr i
|
|
}
|
|
|
|
if {$is_windows} {
|
|
global kill_stunnel
|
|
checkbutton .o.b$i -anchor w -variable kill_stunnel -text \
|
|
"Kill Stunnel Automatically"
|
|
incr i
|
|
}
|
|
|
|
|
|
menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable compresslevel_text -relief groove
|
|
set compresslevel_text "Compress Level: $use_compresslevel"
|
|
if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
set darwin_cotvnc_blist(.o.b$i) 1
|
|
|
|
menu .o.b$i.m -tearoff 0
|
|
for {set j -1} {$j < 10} {incr j} {
|
|
set v $j
|
|
set l $j
|
|
if {$j == -1} {
|
|
set v "default"
|
|
set l "default"
|
|
}
|
|
.o.b$i.m add radiobutton -variable use_compresslevel \
|
|
-value $v -label $l -command \
|
|
{set compresslevel_text "Compress Level: $use_compresslevel"}
|
|
}
|
|
incr i
|
|
|
|
menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable quality_text -relief groove
|
|
set quality_text "Quality: $use_quality"
|
|
if {$darwin_cotvnc} {.o.b$i configure -state disabled}
|
|
set darwin_cotvnc_blist(.o.b$i) 1
|
|
|
|
menu .o.b$i.m -tearoff 0
|
|
for {set j -1} {$j < 10} {incr j} {
|
|
set v $j
|
|
set l $j
|
|
if {$j == -1} {
|
|
set v "default"
|
|
set l "default"
|
|
}
|
|
.o.b$i.m add radiobutton -variable use_quality \
|
|
-value $v -label $l -command \
|
|
{set quality_text "Quality: $use_quality"}
|
|
}
|
|
incr i
|
|
|
|
global use_mode ts_only ssh_only
|
|
if {$ts_only} {
|
|
set use_mode "Terminal Services (tsvnc)"
|
|
} elseif {$ssh_only} {
|
|
set use_mode "SSH-Only (sshvnc)"
|
|
} else {
|
|
set use_mode "SSVNC"
|
|
}
|
|
global mode_text
|
|
set mode_text "Mode: $use_mode"
|
|
|
|
menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable mode_text -relief groove
|
|
|
|
menu .o.b$i.m -tearoff 0
|
|
.o.b$i.m add radiobutton -variable use_mode -value "SSVNC" \
|
|
-label "SSVNC" -command { if {$ts_only || $ssh_only} {to_ssvnc; set mode_text "Mode: SSVNC"; destroy .o}}
|
|
.o.b$i.m add radiobutton -variable use_mode -value "SSH-Only (sshvnc)" \
|
|
-label "SSH-Only (sshvnc)" -command { if {$ts_only || ! $ssh_only} {to_sshonly; set mode_text "Mode: SSH-Only (sshvnc)"; destroy .o}}
|
|
.o.b$i.m add radiobutton -variable use_mode -value "Terminal Services (tsvnc)" \
|
|
-label "Terminal Services (tsvnc)" -command {to_tsonly; set mode_text "Mode: Terminal Services (tsvnc)"; destroy .o}
|
|
incr i
|
|
|
|
global started_with_noenc
|
|
|
|
if {0 && $started_with_noenc && $showing_no_encryption} {
|
|
;
|
|
} elseif {$ssh_only} {
|
|
;
|
|
} else {
|
|
checkbutton .o.b$i -anchor w -variable showing_no_encryption -text \
|
|
"Show 'No Encryption' Option" -pady 5 \
|
|
-command {toggle_no_encryption 1}
|
|
# -relief raised
|
|
incr i
|
|
}
|
|
|
|
for {set j 1} {$j < $i} {incr j} {
|
|
global ssh_only ts_only
|
|
if {$ssh_only && $j <= 3} {
|
|
continue;
|
|
}
|
|
if {$ts_only && $j <= 3} {
|
|
continue;
|
|
}
|
|
if {!$showing_no_encryption && $j == $ine} {
|
|
continue;
|
|
}
|
|
|
|
pack .o.b$j -side top -fill x
|
|
}
|
|
|
|
if {$is_windows} {
|
|
global port_slot putty_pw
|
|
|
|
frame .o.pp
|
|
frame .o.pp.fL
|
|
frame .o.pp.fR
|
|
label .o.pp.fL.la -anchor w -text "Putty PW:"
|
|
label .o.pp.fL.lb -anchor w -text "Port Slot:"
|
|
pack .o.pp.fL.la .o.pp.fL.lb -side top -fill x
|
|
|
|
entry .o.pp.fR.ea -width 10 -show * -textvariable putty_pw
|
|
entry .o.pp.fR.eb -width 10 -textvariable port_slot
|
|
pack .o.pp.fR.ea .o.pp.fR.eb -side top -fill x
|
|
|
|
pack .o.pp.fL -side left
|
|
pack .o.pp.fR -side right -expand 1 -fill x
|
|
|
|
pack .o.pp -side top -fill x
|
|
|
|
putty_pw_entry check
|
|
}
|
|
|
|
global uname
|
|
set t1 " Advanced ..."
|
|
set t2 " Use Defaults"
|
|
set t3 " Delete Profile ..."
|
|
if {$uname == "Darwin"} {
|
|
regsub {^ *} $t1 "" t1
|
|
regsub {^ *} $t2 "" t2
|
|
regsub {^ *} $t3 "" t3
|
|
}
|
|
|
|
button .o.advanced -anchor w -text $t1 -command set_advanced_options
|
|
button .o.clear -anchor w -text $t2 -command {set_defaults; init_vncdisplay}
|
|
button .o.delete -anchor w -text $t3 -command {destroy .o; delete_profile}
|
|
|
|
pack .o.clear -side top -fill x
|
|
pack .o.delete -side top -fill x
|
|
pack .o.advanced -side top -fill x
|
|
|
|
# pack .o.s_prof -side top -fill x
|
|
# pack .o.l_prof -side top -fill x
|
|
|
|
frame .o.b
|
|
button .o.b.done -text "Done" -command {destroy .o}
|
|
bind .o <Escape> {destroy .o}
|
|
wm protocol .o WM_DELETE_WINDOW {destroy .o}
|
|
button .o.b.help -text "Help" -command help_opts
|
|
global use_listen
|
|
if {$use_listen} {
|
|
button .o.b.connect -text "Listen" -command launch
|
|
} else {
|
|
button .o.b.connect -text "Connect" -command launch
|
|
}
|
|
|
|
pack .o.b.help .o.b.connect .o.b.done -fill x -expand 1 -side left
|
|
|
|
pack .o.b -side top -fill x
|
|
|
|
center_win .o
|
|
wm resizable .o 1 0
|
|
focus .o
|
|
}
|
|
|
|
proc check_writable {} {
|
|
set test test[pid].txt
|
|
catch {set f [open $test "w"]; puts $f "test"; close $f}
|
|
|
|
###catch {file delete -force $test} # testing.
|
|
|
|
if ![file exists $test] {
|
|
global env
|
|
if [info exists env(SSVNC_HOME)] {
|
|
set dir "$env(SSVNC_HOME)/ss_vnc/cache"
|
|
catch {file mkdir $dir}
|
|
if ![file exists $dir] {
|
|
return
|
|
}
|
|
foreach f [glob -type f * */* */*/*] {
|
|
set dest "$dir/$f"
|
|
set dirn [file dirname $dest]
|
|
catch {file mkdir $dirn}
|
|
catch {file copy -force -- $f $dest}
|
|
}
|
|
cd $dir
|
|
###catch {set f [open $test "w"]; puts $f "test"; close $f}
|
|
}
|
|
} else {
|
|
catch {file delete -force $test}
|
|
}
|
|
}
|
|
|
|
proc print_help {} {
|
|
|
|
global help_main help_prox help_misc help_tips
|
|
set b "\n============================================================================\n"
|
|
help
|
|
#set str [.h.f.t get 1.0 end]
|
|
#puts "${b}Help:\n$str"
|
|
puts "${b}Help Main:\n$help_main"
|
|
puts "${b}Help Proxies:\n$help_prox"
|
|
puts "${b}Help Misc:\n$help_misc"
|
|
puts "${b}Help Tips:\n$help_tips"
|
|
destroy .h
|
|
|
|
help_opts
|
|
set str [.oh.f.t get 1.0 end]
|
|
puts "${b}SSL/SSH Viewer Options Help:\n$str"
|
|
destroy .oh
|
|
|
|
help_advanced_opts
|
|
set str [.ah.f.t get 1.0 end]
|
|
puts "${b}Advanced Options Help:\n$str"
|
|
destroy .ah
|
|
|
|
help_ssvncviewer_opts
|
|
set str [.av.f.t get 1.0 end]
|
|
puts "${b}ssvncviewer Options Help:\n$str"
|
|
destroy .av
|
|
|
|
help_certs
|
|
set str [.ch.f.t get 1.0 end]
|
|
puts "${b}SSL Certificates Help:\n$str"
|
|
destroy .ch
|
|
|
|
help_fetch_cert
|
|
set str [.fh.f.t get 1.0 end]
|
|
puts "${b}Fetch Certificates Help:\n$str"
|
|
destroy .fh
|
|
|
|
create_cert
|
|
set str [.ccrt.f.t get 1.0 end]
|
|
puts "${b}Create SSL Certificate Dialog:\n$str"
|
|
destroy .ccrt
|
|
|
|
import_cert
|
|
set str [.icrt.f.t get 1.0 end]
|
|
puts "${b}Import SSL Certificate Dialog:\n$str"
|
|
destroy .icrt
|
|
|
|
global cert_text
|
|
set cert_text "empty"
|
|
save_cert "help:0"
|
|
set str [.scrt.f.t get 1.0 end]
|
|
puts "${b}Save SSL Certificate Dialog:\n$str"
|
|
destroy .scrt
|
|
|
|
ts_help
|
|
set str [.h.f.t get 1.0 end]
|
|
puts "${b}Terminal Services Help:\n$str"
|
|
destroy .h
|
|
|
|
help_ts_opts
|
|
set str [.oh.f.t get 1.0 end]
|
|
puts "${b}Terminal Services VNC Options Help:\n$str"
|
|
destroy .oh
|
|
|
|
ts_unixpw_dialog
|
|
set str [.uxpw.f.t get 1.0 end]
|
|
puts "${b}Terminal Services Use unixpw Dialog:\n$str"
|
|
destroy .uxpw
|
|
|
|
ts_vncshared_dialog
|
|
set str [.vncs.f.t get 1.0 end]
|
|
puts "${b}Terminal Services VNC Shared Dialog:\n$str"
|
|
destroy .vncs
|
|
|
|
ts_multi_dialog
|
|
set str [.mult.f.t get 1.0 end]
|
|
puts "${b}Terminal Services Multiple Sessions Dialog:\n$str"
|
|
destroy .mult
|
|
|
|
ts_xlogin_dialog
|
|
set str [.xlog.f.t get 1.0 end]
|
|
puts "${b}Terminal Services X Login Dialog:\n$str"
|
|
destroy .xlog
|
|
|
|
ts_othervnc_dialog
|
|
set str [.ovnc.f.t get 1.0 end]
|
|
puts "${b}Terminal Services Other VNC Server Dialog:\n$str"
|
|
destroy .ovnc
|
|
|
|
ts_ncache_dialog
|
|
set str [.nche.f.t get 1.0 end]
|
|
puts "${b}Terminal Services Client-Side Caching Dialog:\n$str"
|
|
destroy .nche
|
|
|
|
ts_x11vnc_opts_dialog
|
|
set str [.x11v.f.t get 1.0 end]
|
|
puts "${b}Terminal Services x11vnc Options Dialog:\n$str"
|
|
destroy .x11v
|
|
|
|
ts_filexfer_dialog
|
|
set str [.xfer.f.t get 1.0 end]
|
|
puts "${b}Terminal Services File Transfer Dialog:\n$str"
|
|
destroy .xfer
|
|
|
|
ts_sound_dialog
|
|
set str [.snd.f.t get 1.0 end]
|
|
puts "${b}Terminal Services Sound Tunnelling Dialog:\n$str"
|
|
destroy .snd
|
|
|
|
ts_cups_dialog
|
|
set str [.cups.f.t get 1.0 end]
|
|
puts "${b}Terminal Services CUPS Dialog:\n$str"
|
|
destroy .cups
|
|
|
|
help_ssvncviewer_opts
|
|
set str [.av.f.t get 1.0 end]
|
|
puts "${b}Unix SSVNC viewer Options Help:\n$str"
|
|
destroy .av
|
|
|
|
change_vncviewer_dialog
|
|
set str [.chviewer.t get 1.0 end]
|
|
puts "${b}Unix Change VNC Viewer Dialog:\n$str"
|
|
destroy .chviewer
|
|
|
|
cups_dialog
|
|
set str [.cups.f.t get 1.0 end]
|
|
puts "${b}CUPS Dialog:\n$str"
|
|
destroy .cups
|
|
|
|
sound_dialog
|
|
set str [.snd.f.t get 1.0 end]
|
|
puts "${b}ESD Audio Tunnelling Dialog:\n$str"
|
|
destroy .snd
|
|
|
|
smb_dialog
|
|
set str [.smb.f.t get 1.0 end]
|
|
puts "${b}SMB Mounting Dialog:\n$str"
|
|
destroy .smb
|
|
|
|
port_redir_dialog
|
|
set str [.redirs.t get 1.0 end]
|
|
puts "${b}Additional Port Redirections Dialog:\n$str"
|
|
destroy .redirs
|
|
|
|
port_knocking_dialog
|
|
set str [.pk.f.t get 1.0 end]
|
|
puts "${b}Port Knocking Dialog:\n$str"
|
|
destroy .pk
|
|
|
|
ssvnc_escape_help
|
|
set str [.ekh.f.t get 1.0 end]
|
|
puts "${b}SSVNC Escape Keys Help:\n$str"
|
|
destroy .ekh
|
|
|
|
stunnel_sec_dialog
|
|
set str [.stlsec.f.t get 1.0 end]
|
|
puts "${b}STUNNEL Local Port Protections Dialog:\n$str"
|
|
destroy .stlsec
|
|
|
|
disable_ssl_workarounds_dialog
|
|
set str [.sslwrk.f.t get 1.0 end]
|
|
puts "${b}Disable SSL Workarounds Dialog:\n$str"
|
|
destroy .sslwrk
|
|
|
|
ultra_dsm_dialog
|
|
set str [.ultradsm.f.t get 1.0 end]
|
|
puts "${b}UltraVNC DSM Encryption Plugin Dialog:\n$str"
|
|
destroy .ultradsm
|
|
|
|
ssh_known_hosts_dialog
|
|
set str [.sshknownhosts.f.t get 1.0 end]
|
|
puts "${b}Private SSH KnownHosts file Dialog:\n$str"
|
|
destroy .sshknownhosts
|
|
|
|
ssh_sec_dialog
|
|
set str [.sshsec.t get 1.0 end]
|
|
puts "${b}SSH Local Port Protections Dialog:\n$str"
|
|
destroy .sshsec
|
|
|
|
multilisten_dialog
|
|
set str [.multil.t get 1.0 end]
|
|
puts "${b}Multiple LISTEN Connections Dialog:\n$str"
|
|
destroy .multil
|
|
|
|
use_grab_dialog
|
|
set str [.usegrb.t get 1.0 end]
|
|
puts "${b}Use XGrabServer (for fullscreen) Dialog:\n$str"
|
|
destroy .usegrb
|
|
}
|
|
|
|
proc zeroconf_fill {b m} {
|
|
global is_windows zeroconf_command last_post
|
|
|
|
if {$is_windows} {
|
|
return;
|
|
}
|
|
|
|
if {![info exists last_post]} {
|
|
set last_post 0
|
|
}
|
|
set now [clock seconds]
|
|
if {$now < [expr $last_post + 10]} {
|
|
# cache menu for 10 secs.
|
|
return
|
|
}
|
|
|
|
. config -cursor {watch}
|
|
$b config -cursor {watch}
|
|
$b configure -state disabled
|
|
|
|
$m delete 0 end
|
|
update
|
|
|
|
set emsg ""
|
|
set output ""
|
|
set none "No VNC servers detected"
|
|
|
|
set rc 1
|
|
set rd 0
|
|
if {$zeroconf_command == "avahi-browse"} {
|
|
set rc [catch {set output [exec avahi-browse -r -t -p -k _rfb._tcp 2>/dev/null]} emsg]
|
|
} elseif {$zeroconf_command == "dns-sd"} {
|
|
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]
|
|
set rd 1
|
|
} elseif {$zeroconf_command == "mDNS"} {
|
|
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]
|
|
set rd 1
|
|
}
|
|
|
|
#puts "rc=$rc output=$output"
|
|
if {$rd == 1 && $rc != 0} {
|
|
if [regexp {_rfb} $emsg] {
|
|
set rc 0
|
|
set output $emsg
|
|
}
|
|
}
|
|
|
|
set count 0
|
|
|
|
if {$rc != 0} {
|
|
$m add command -label $none
|
|
incr count
|
|
|
|
} elseif {$output == "" || [regexp {^[ \t\n]*$} $output]} {
|
|
$m add command -label $none
|
|
incr count
|
|
|
|
} elseif {$zeroconf_command == "avahi-browse"} {
|
|
set lines [split $output "\n"]
|
|
set saw("__none__") 1
|
|
foreach line $lines {
|
|
set items [split $line ";"]
|
|
if {[llength $items] != 10} {
|
|
continue
|
|
}
|
|
if {[lindex $items 0] != "="} {
|
|
continue
|
|
}
|
|
|
|
# =;eth0;IPv4;tmp2\0582;_rfb._tcp;local;tmp2.local;10.0.2.252;5902;
|
|
set eth [lindex $items 1]
|
|
set ipv [lindex $items 2]
|
|
set name [lindex $items 3]
|
|
set type [lindex $items 4]
|
|
set loc [lindex $items 5]
|
|
set host [lindex $items 6]
|
|
set ip [lindex $items 7]
|
|
set port [lindex $items 8]
|
|
|
|
if {![regexp -nocase {ipv4} $ipv]} {
|
|
continue
|
|
}
|
|
|
|
set name0 $name
|
|
regsub -all {\\\\} $name "__bockslosh__" name
|
|
regsub -all {\\\.} $name "." name
|
|
|
|
set n 0
|
|
while {1} {
|
|
incr n
|
|
if {$n > 100} {
|
|
break
|
|
}
|
|
if {[regexp {\\[0-9][0-9][0-9]} $name match]} {
|
|
#puts "match1=$match"
|
|
regsub {\\} $match "" match
|
|
set d $match
|
|
regsub {^0*} $d "" d
|
|
set c [format "%c" $d]
|
|
if {"$c" == "&"} {
|
|
set c "\\$c"
|
|
}
|
|
regsub "\\\\$match" $name $c name
|
|
#puts "match: $match c='$c'\nname=$name"
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
regsub -all {__bockslosh__} $name "\\" name
|
|
|
|
set hp $host
|
|
if {$port >= 5900 && $port <= 6100} {
|
|
set d [expr $port - 5900]
|
|
set hp "$host:$d"
|
|
} else {
|
|
set hp "$host:$port"
|
|
}
|
|
if {![info exists saw($name)]} {
|
|
regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp
|
|
$m add command -label "$name - $hp" -command "set vncdisplay \"$hp\""
|
|
incr count
|
|
set p $port
|
|
if {$p <= 200} {
|
|
set p "-$port"
|
|
}
|
|
regsub -all {[^[:alnum:],./:@%_=+-]} "$ip:$p" "" ipp
|
|
$m add command -label "$name - $ipp" -command "set vncdisplay \"$ipp\""
|
|
incr count
|
|
set saw($name) 1
|
|
}
|
|
}
|
|
} else {
|
|
set lines [split $output "\n"]
|
|
set saw("__none__") 1
|
|
global dns_sd_cache last_dns_sd
|
|
if {![info exists last_dns_sd]} {
|
|
set last_dns_sd 0
|
|
}
|
|
if {[clock seconds] > [expr $last_dns_sd + 1800]} {
|
|
catch { unset dns_sd_cache }
|
|
set last_dns_sd [clock seconds]
|
|
}
|
|
foreach line $lines {
|
|
if [regexp -nocase {^Browsing} $line] {
|
|
continue;
|
|
}
|
|
if [regexp -nocase {^Timestamp} $line] {
|
|
continue;
|
|
}
|
|
if [regexp -nocase {killed:} $line] {
|
|
continue;
|
|
}
|
|
if {![regexp {_rfb\._tcp} $line]} {
|
|
continue;
|
|
}
|
|
regsub {[ \t\n]*$} $line "" line
|
|
regsub {^.*_rfb\._tcp[^ ]* *} $line "" name
|
|
|
|
if {[info exists saw($name)]} {
|
|
continue
|
|
}
|
|
set saw($name) 1
|
|
|
|
set hp "$name"
|
|
if {[info exists dns_sd_cache($name)]} {
|
|
set hp $dns_sd_cache($name)
|
|
} else {
|
|
global env
|
|
regsub -all {"} $name "" name2
|
|
set env(DNS_SD_LU) $name2
|
|
set emsg ""
|
|
if {$zeroconf_command == "dns-sd"} {
|
|
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]
|
|
} elseif {$zeroconf_command == "mDNS"} {
|
|
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]
|
|
regsub -all {[ \t][ \t]*:} $emsg ":" emsg
|
|
}
|
|
regsub -all { *} $emsg " " emsg
|
|
if [regexp -nocase {be reached at *([^ \t\n][^ \t\n]*)} $emsg match hpm] {
|
|
if [regexp {^(.*):([0-9][0-9]*)$} $hpm mv hm pm] {
|
|
if {$pm >= 5900 && $pm <= 6100} {
|
|
set pm [expr $pm - 5900]
|
|
}
|
|
set hp "$hm:$pm"
|
|
} else {
|
|
set hp $hpm
|
|
}
|
|
set dns_sd_cache($name) $hp
|
|
} else {
|
|
set hp "$name"
|
|
if {![regexp {:[0-9][0-9]*$} $hp]} {
|
|
set hp "$name:0"
|
|
}
|
|
}
|
|
}
|
|
regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp
|
|
$m add command -label "$name - $hp" -command "set vncdisplay \"$hp\""
|
|
incr count
|
|
}
|
|
}
|
|
$b configure -state normal
|
|
. config -cursor {}
|
|
$b config -cursor {}
|
|
if {$count == 0} {
|
|
$m add command -label $none
|
|
}
|
|
set last_post [clock seconds]
|
|
}
|
|
|
|
proc check_zeroconf_browse {} {
|
|
global is_windows zeroconf_command
|
|
|
|
set zeroconf_command ""
|
|
if {$is_windows} {
|
|
return 0;
|
|
}
|
|
set p ""
|
|
set r [catch {set p [exec /bin/sh -c {type avahi-browse}]}]
|
|
if {$r == 0} {
|
|
regsub {^.* is *} $p "" p
|
|
regsub -all {[ \t\n\r]} $p "" p
|
|
if [file exists $p] {
|
|
set zeroconf_command "avahi-browse"
|
|
return 1
|
|
}
|
|
}
|
|
set p ""
|
|
set r [catch {set p [exec /bin/sh -c {type dns-sd}]}]
|
|
if {$r == 0} {
|
|
regsub {^.* is *} $p "" p
|
|
regsub -all {[ \t\n\r]} $p "" p
|
|
if [file exists $p] {
|
|
set zeroconf_command "dns-sd"
|
|
global env
|
|
if [info exists env(USE_MDNS)] {
|
|
# testing
|
|
set zeroconf_command "mDNS"
|
|
}
|
|
return 1
|
|
}
|
|
}
|
|
set p ""
|
|
set r [catch {set p [exec /bin/sh -c {type mDNS}]}]
|
|
if {$r == 0} {
|
|
regsub {^.* is *} $p "" p
|
|
regsub -all {[ \t\n\r]} $p "" p
|
|
if [file exists $p] {
|
|
set zeroconf_command "mDNS"
|
|
return 1
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc toggle_no_encryption {{rev 0}} {
|
|
global showing_no_encryption
|
|
global no_enc_button no_enc_prev
|
|
global ts_only ssh_only
|
|
global use_ssl use_ssh use_sshssl
|
|
|
|
if {$rev} {
|
|
# reverse it first
|
|
if {$showing_no_encryption} {
|
|
set showing_no_encryption 0
|
|
} else {
|
|
set showing_no_encryption 1
|
|
}
|
|
}
|
|
|
|
if {$showing_no_encryption} {
|
|
catch {pack forget .f4.none}
|
|
catch {pack forget $no_enc_button}
|
|
if {!$use_ssl && !$use_ssh && !$use_sshssl} {
|
|
set use_ssl 1
|
|
sync_use_ssl_ssh
|
|
}
|
|
set showing_no_encryption 0
|
|
} else {
|
|
if {$ts_only || $ssh_only} {
|
|
return
|
|
}
|
|
catch {pack .f4.none -side left}
|
|
if {![info exists no_enc_button]} {
|
|
catch {destroy .o}
|
|
} elseif {![winfo exists $no_enc_button]} {
|
|
catch {destroy .o}
|
|
} else {
|
|
catch {pack $no_enc_button -after $no_enc_prev -fill x}
|
|
}
|
|
set showing_no_encryption 1
|
|
}
|
|
}
|
|
|
|
proc toggle_vnc_prefix {} {
|
|
global vncdisplay
|
|
if [regexp -nocase {^vnc://} $vncdisplay] {
|
|
regsub -nocase {^vnc://} $vncdisplay "" vncdisplay
|
|
} else {
|
|
regsub -nocase {^[a-z0-9+]*://} $vncdisplay "" vncdisplay
|
|
set vncdisplay "Vnc://$vncdisplay"
|
|
}
|
|
catch {.f0.e icursor end}
|
|
}
|
|
|
|
############################################
|
|
|
|
global env
|
|
|
|
if {[regexp -nocase {Windows.9} $tcl_platform(os)]} {
|
|
set is_win9x 1
|
|
} else {
|
|
set is_win9x 0
|
|
}
|
|
|
|
set is_windows 0
|
|
if { [regexp -nocase {Windows} $tcl_platform(os)]} {
|
|
set is_windows 1
|
|
}
|
|
|
|
set uname ""
|
|
if {! $is_windows} {
|
|
catch {set uname [exec uname]}
|
|
}
|
|
|
|
set ffont "fixed"
|
|
|
|
global have_ipv6
|
|
set have_ipv6 ""
|
|
check_for_ipv6
|
|
|
|
# need to check if "fixed" font under XFT on tk8.5 is actually fixed width!!
|
|
if {$tcl_platform(platform) == "unix"} {
|
|
set ls ""
|
|
catch {set ls [font metrics $ffont -linespace]}
|
|
set fs ""
|
|
catch {set fs [font metrics $ffont -fixed]}
|
|
set redo 0
|
|
if {$fs != "" && $fs != "1"} {
|
|
set redo 1
|
|
}
|
|
if {$ls != "" && $ls > 14} {
|
|
set redo 1
|
|
}
|
|
if {$redo} {
|
|
foreach fn [font names] {
|
|
if {$fn == "TkFixedFont"} {
|
|
set ffont $fn
|
|
break
|
|
}
|
|
}
|
|
}
|
|
catch {option add *Dialog.msg.font {helvetica -14 bold}}
|
|
catch {option add *Dialog.msg.wrapLength 4i}
|
|
}
|
|
|
|
if {$uname == "Darwin"} {
|
|
set ffont "Monaco 10"
|
|
|
|
#option add *Button.font Helvetica widgetDefault
|
|
catch {option add *Button.font {System 10} widgetDefault}
|
|
}
|
|
|
|
# set SSVNC_HOME to HOME in case we modify it for mobile use:
|
|
if [info exists env(HOME)] {
|
|
if {! [info exists env(SSVNC_HOME)]} {
|
|
set env(SSVNC_HOME) $env(HOME)
|
|
}
|
|
}
|
|
|
|
# For mobile use, e.g. from a USB flash drive, we look for a "home" or "Home"
|
|
# directory relative to this script where the profiles and certs will be kept
|
|
# by default.
|
|
if [file exists $buck_zero] {
|
|
#puts "$buck_zero"
|
|
set up [file dirname $buck_zero]
|
|
|
|
if {$up == "."} {
|
|
# this is actually bad news on windows because we cd'd to util.
|
|
set up ".."
|
|
} else {
|
|
set up [file dirname $up]
|
|
}
|
|
set dirs [list $up]
|
|
|
|
if {! $is_windows && $up != ".."} {
|
|
# get rid of bin
|
|
set up [file dirname $up]
|
|
lappend dirs $up
|
|
}
|
|
|
|
for {set i 0} {$i < $argc} {incr i} {
|
|
set it0 [lindex $argv $i]
|
|
if {$it0 == "."} {
|
|
if {![file isdirectory "$up/home"] && ![file isdirectory "$up/Home"]} {
|
|
catch {file mkdir "$up/Home"}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
set gotone 0
|
|
|
|
foreach d $dirs {
|
|
set try "$d/home"
|
|
#puts "$try"
|
|
if [file isdirectory $try] {
|
|
set env(SSVNC_HOME) $try
|
|
set gotone 1
|
|
break
|
|
}
|
|
set try "$d/Home"
|
|
#puts "$try"
|
|
if [file isdirectory $try] {
|
|
set env(SSVNC_HOME) $try
|
|
set gotone 1
|
|
break
|
|
}
|
|
}
|
|
if {$gotone} {
|
|
set b ""
|
|
if {$is_windows} {
|
|
set b "$env(SSVNC_HOME)/ss_vnc"
|
|
} else {
|
|
set b "$env(SSVNC_HOME)/.vnc"
|
|
}
|
|
catch {file mkdir $b}
|
|
catch {file mkdir "$b/certs"}
|
|
catch {file mkdir "$b/profiles"}
|
|
}
|
|
#puts "HOME: $env(SSVNC_HOME)"
|
|
}
|
|
|
|
global svcert_default mycert_default crlfil_default
|
|
global svcert_default_force mycert_default_force crlfil_default_force
|
|
set svcert_default ""
|
|
set mycert_default ""
|
|
set crlfil_default ""
|
|
set svcert_default_force 0
|
|
set mycert_default_force 0
|
|
set crlfil_default_force 0
|
|
|
|
set saw_ts_only 0
|
|
set saw_ssh_only 0
|
|
|
|
set ssvncrc $env(SSVNC_HOME)/.ssvncrc
|
|
if {$is_windows} {
|
|
set ssvncrc $env(SSVNC_HOME)/ssvnc_rc
|
|
}
|
|
|
|
global ts_desktop_size_def ts_desktop_depth_def ts_desktop_type_def ts_xserver_type_def
|
|
set ts_desktop_size_def ""
|
|
set ts_desktop_depth_def ""
|
|
set ts_desktop_type_def ""
|
|
set ts_xserver_type_def ""
|
|
|
|
global win_localhost
|
|
set win_localhost "127.0.0.1"
|
|
|
|
global kill_stunnel
|
|
set kill_stunnel 1
|
|
|
|
global started_with_noenc
|
|
|
|
if {! [info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} {
|
|
set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
|
|
set started_with_noenc 1
|
|
} else {
|
|
if {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "0"} {
|
|
set started_with_noenc 0
|
|
} elseif {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "1"} {
|
|
set started_with_noenc 1
|
|
} else {
|
|
set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
|
|
set started_with_noenc 1
|
|
}
|
|
}
|
|
|
|
if [file exists $ssvncrc] {
|
|
set fh ""
|
|
catch {set fh [open $ssvncrc "r"]}
|
|
if {$fh != ""} {
|
|
while {[gets $fh line] > -1} {
|
|
set str [string trim $line]
|
|
if [regexp {^#} $str] {
|
|
continue
|
|
}
|
|
if [regexp {^mode=tsvnc} $str] {
|
|
set saw_ts_only 1
|
|
set saw_ssh_only 0
|
|
} elseif [regexp {^mode=sshvnc} $str] {
|
|
set saw_ts_only 0
|
|
set saw_ssh_only 1
|
|
} elseif [regexp {^mode=ssvnc} $str] {
|
|
set saw_ts_only 0
|
|
set saw_ssh_only 0
|
|
}
|
|
if [regexp {^desktop_type=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set ts_desktop_type_def $val
|
|
}
|
|
if [regexp {^desktop_size=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set ts_desktop_size_def $val
|
|
}
|
|
if [regexp {^desktop_depth=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set ts_desktop_depth_def $val
|
|
}
|
|
if [regexp {^xserver_type=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set ts_xserver_type_def $val
|
|
}
|
|
if [regexp {^font_default=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
catch {option add *font $val}
|
|
catch {option add *Dialog.msg.font $val}
|
|
}
|
|
if [regexp {^font_fixed=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set ffont $val
|
|
}
|
|
if [regexp {^noenc=1} $str] {
|
|
global env
|
|
set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
|
|
set started_with_noenc 1
|
|
}
|
|
if [regexp {^noenc=0} $str] {
|
|
global env
|
|
set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0
|
|
set started_with_noenc 0
|
|
}
|
|
if [regexp {^cotvnc=1} $str] {
|
|
global env
|
|
set env(SSVNC_COTVNC) 1
|
|
}
|
|
if [regexp {^cotvnc=0} $str] {
|
|
global env
|
|
set env(SSVNC_COTVNC) 0
|
|
}
|
|
if [regexp {^killstunnel=1} $str] {
|
|
set kill_stunnel 1
|
|
}
|
|
if [regexp {^killstunnel=0} $str] {
|
|
set kill_stunnel 0
|
|
}
|
|
global have_ipv6
|
|
if [regexp {^ipv6=1} $str] {
|
|
set have_ipv6 1
|
|
set env(SSVNC_IPV6) 1
|
|
}
|
|
if [regexp {^ipv6=0} $str] {
|
|
set have_ipv6 0
|
|
set env(SSVNC_IPV6) 0
|
|
}
|
|
if [regexp {^mycert=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set mycert_default $val
|
|
}
|
|
if [regexp {^cert=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set mycert_default $val
|
|
}
|
|
if [regexp {^cacert=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set svcert_default $val
|
|
}
|
|
if [regexp {^ca=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set svcert_default $val
|
|
}
|
|
if [regexp {^crl=(.*)$} $str m val] {
|
|
set val [string trim $val]
|
|
set crlfil_default $val
|
|
}
|
|
if [regexp {^env=([^=]*)=(.*)$} $str m var val] {
|
|
global env
|
|
set env($var) $val
|
|
}
|
|
}
|
|
close $fh
|
|
}
|
|
}
|
|
|
|
for {set i 0} {$i < $argc} {incr i} {
|
|
set item [lindex $argv $i]
|
|
regsub {^--} $item "-" item
|
|
if {$item == "-profiles" || $item == "-list"} {
|
|
set dir [get_profiles_dir]
|
|
#puts stderr "VNC Profiles:"
|
|
#puts stderr " "
|
|
if {[info exists env(SSVNC_TS_ONLY)]} {
|
|
set saw_ts_only 1
|
|
} elseif {[info exists env(SSVNC_SSH_ONLY)]} {
|
|
set saw_ssh_only 1
|
|
}
|
|
set profs [list]
|
|
foreach prof [glob -nocomplain -directory $dir "*.vnc"] {
|
|
set s [file tail $prof]
|
|
regsub {\.vnc$} $s "" s
|
|
if {$saw_ts_only || $saw_ssh_only} {
|
|
set ok 0;
|
|
set tsok 0;
|
|
set fh ""
|
|
catch {set fh [open $prof "r"]}
|
|
if {$fh != ""} {
|
|
while {[gets $fh line] > -1} {
|
|
if {[regexp {use_ssh=1} $line]} {
|
|
set ok 1
|
|
}
|
|
if {[regexp {ts_mode=1} $line]} {
|
|
set tsok 1
|
|
}
|
|
}
|
|
close $fh
|
|
}
|
|
if {$saw_ts_only && !$tsok} {
|
|
continue;
|
|
} elseif {! $ok} {
|
|
continue
|
|
}
|
|
}
|
|
lappend profs $s
|
|
}
|
|
foreach prof [lsort $profs] {
|
|
puts "$prof"
|
|
}
|
|
exit
|
|
} elseif {$item == "-nvb"} {
|
|
global env
|
|
set env(SSVNC_NO_VERIFY_ALL_BUTTON) 1
|
|
} elseif {$item == "-noenc"} {
|
|
global env
|
|
set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
|
|
set started_with_noenc 1
|
|
} elseif {$item == "-enc"} {
|
|
global env
|
|
set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0
|
|
} elseif {$item == "-bigger"} {
|
|
global env
|
|
if {![info exists env(SSVNC_BIGGER_DIALOG)]} {
|
|
set env(SSVNC_BIGGER_DIALOG) 1
|
|
}
|
|
} elseif {$item == "-ssh"} {
|
|
set saw_ssh_only 1
|
|
set saw_ts_only 0
|
|
} elseif {$item == "-ts"} {
|
|
set saw_ts_only 1
|
|
set saw_ssh_only 0
|
|
} elseif {$item == "-ssl" || $item == "-ss"} {
|
|
set saw_ts_only 0
|
|
set saw_ssh_only 0
|
|
} elseif {$item == "-tso"} {
|
|
global env
|
|
set env(SSVNC_TS_ALWAYS) 1
|
|
set saw_ts_only 1
|
|
} elseif {$item == "-killstunnel"} {
|
|
set kill_stunnel 1
|
|
} elseif {$item == "-nokillstunnel"} {
|
|
set kill_stunnel 0
|
|
} elseif {$item == "-mycert" || $item == "-cert"} {
|
|
incr i
|
|
set mycert_default [lindex $argv $i]
|
|
} elseif {$item == "-cacert" || $item == "-ca"} {
|
|
incr i
|
|
set svcert_default [lindex $argv $i]
|
|
} elseif {$item == "-crl"} {
|
|
incr i
|
|
set crlfil_default [lindex $argv $i]
|
|
}
|
|
}
|
|
|
|
if [info exists env(SSVNC_FONT_FIXED)] {
|
|
set ffont $env(SSVNC_FONT_FIXED)
|
|
}
|
|
|
|
if [info exists env(SSVNC_FONT_DEFAULT)] {
|
|
catch {option add *font $env(SSVNC_FONT_DEFAULT)}
|
|
catch {option add *Dialog.msg.font $env(SSVNC_FONT_DEFAULT)}
|
|
}
|
|
|
|
if [regexp {[ ]} $ffont] {
|
|
set help_font "-font \"$ffont\""
|
|
} else {
|
|
set help_font "-font $ffont"
|
|
}
|
|
|
|
if { [regexp -nocase {Windows} $tcl_platform(os)]} {
|
|
cd util
|
|
if {$help_font == "-font fixed"} {
|
|
set help_font ""
|
|
}
|
|
}
|
|
|
|
if {$saw_ts_only && $saw_ssh_only} {
|
|
set saw_ssh_only 0
|
|
}
|
|
|
|
global ssh_only
|
|
set ssh_only 0
|
|
if {[info exists env(SSVNC_SSH_ONLY)] || $saw_ssh_only} {
|
|
set ssh_only 1
|
|
}
|
|
|
|
global ts_only
|
|
set ts_only 0
|
|
if {[info exists env(SSVNC_TS_ONLY)] || $saw_ts_only} {
|
|
set ts_only 1
|
|
}
|
|
|
|
if {$mycert_default != ""} {
|
|
if [regexp -nocase {^FORCE:} $mycert_default] {
|
|
set mycert_default_force 1
|
|
regsub -nocase {^FORCE:} $mycert_default "" mycert_default
|
|
}
|
|
if {![file exists $mycert_default]} {
|
|
set idir [get_idir_certs ""]
|
|
set mycert_default "$idir/$mycert_default"
|
|
}
|
|
}
|
|
|
|
if {$svcert_default != ""} {
|
|
if [regexp -nocase {^FORCE:} $svcert_default] {
|
|
set svcert_default_force 1
|
|
regsub -nocase {^FORCE:} $svcert_default "" svcert_default
|
|
}
|
|
if {![file exists $svcert_default]} {
|
|
set idir [get_idir_certs ""]
|
|
if {$svcert_default == "CA"} {
|
|
set svcert_default "$idir/CA/cacert.pem"
|
|
} else {
|
|
set svcert_default "$idir/$svcert_default"
|
|
}
|
|
}
|
|
}
|
|
|
|
if {$crlfil_default != ""} {
|
|
if [regexp -nocase {^FORCE:} $crlfil_default] {
|
|
set crlfil_default_force 1
|
|
regsub -nocase {^FORCE:} $crlfil_default "" crlfil_default
|
|
}
|
|
if {![file exists $crlfil_default]} {
|
|
set idir [get_idir_certs ""]
|
|
set crlfil_default "$idir/$crlfil_default"
|
|
}
|
|
}
|
|
|
|
if {$is_windows} {
|
|
check_writable
|
|
}
|
|
|
|
|
|
set darwin_cotvnc 0
|
|
if {$uname == "Darwin"} {
|
|
if {! [info exists env(DISPLAY)]} {
|
|
set darwin_cotvnc 1
|
|
} elseif {[regexp {/tmp/} $env(DISPLAY)]} {
|
|
set darwin_cotvnc 1
|
|
}
|
|
if [info exists env(SSVNC_HOME)] {
|
|
set t "$env(SSVNC_HOME)/.vnc"
|
|
if {! [file exists $t]} {
|
|
catch {file mkdir $t}
|
|
}
|
|
}
|
|
}
|
|
|
|
##for testing macosx
|
|
if [info exists env(FORCE_DARWIN)] {
|
|
set uname Darwin
|
|
set darwin_cotvnc 1
|
|
}
|
|
|
|
set putty_pw ""
|
|
|
|
global scroll_text_focus
|
|
set scroll_text_focus 1
|
|
|
|
set multientry 1
|
|
|
|
wm withdraw .
|
|
if {$ssh_only} {
|
|
wm title . "SSH VNC Viewer"
|
|
} elseif {$ts_only} {
|
|
wm title . "Terminal Services VNC Viewer"
|
|
} else {
|
|
wm title . "SSL/SSH VNC Viewer"
|
|
}
|
|
|
|
wm resizable . 1 0
|
|
|
|
set_defaults
|
|
if {$uname == "Darwin"} {
|
|
if [info exists use_x11_macosx] {
|
|
if {$use_x11_macosx} {
|
|
set darwin_cotvnc 0
|
|
}
|
|
}
|
|
}
|
|
set skip_pre 0
|
|
|
|
set vncdisplay ""
|
|
set last_load ""
|
|
set vncproxy ""
|
|
set remote_ssh_cmd ""
|
|
set vncauth_passwd ""
|
|
|
|
global did_listening_message
|
|
set did_listening_message 0
|
|
|
|
global accepted_cert_dialog_in_progress
|
|
set accepted_cert_dialog_in_progress 0
|
|
|
|
global fetch_cert_filename
|
|
set fetch_cert_filename ""
|
|
|
|
set vhd "VNC Host:Display"
|
|
if {$ssh_only} {
|
|
label .l -text "SSH VNC Viewer" -relief ridge
|
|
} elseif {$ts_only} {
|
|
label .l -text "Terminal Services VNC Viewer" -relief ridge
|
|
set vhd "VNC Terminal Server:"
|
|
} else {
|
|
label .l -text "SSL/SSH VNC Viewer" -relief ridge
|
|
}
|
|
|
|
set wl 21
|
|
set we 40
|
|
frame .f0
|
|
if {$multientry} {
|
|
label .f0.l -width $wl -anchor w -text "$vhd" -relief ridge
|
|
} else {
|
|
label .f0.l -anchor w -text "$vhd" -relief ridge
|
|
}
|
|
entry .f0.e -width $we -textvariable vncdisplay
|
|
pack .f0.l -side left
|
|
bind .f0.e <Return> launch
|
|
bind .f0.e <Control-E> {toggle_vnc_prefix}
|
|
pack .f0.e -side left -expand 1 -fill x
|
|
|
|
if {[check_zeroconf_browse]} {
|
|
menubutton .f0.mb -relief ridge -menu .f0.mb.m -text "Find"
|
|
menu .f0.mb.m -tearoff 0 -postcommand {zeroconf_fill .f0.mb .f0.mb.m}
|
|
pack .f0.mb -side left
|
|
}
|
|
|
|
frame .f1
|
|
label .f1.l -width $wl -anchor w -text "VNC Password:" -relief ridge
|
|
entry .f1.e -width $we -textvariable vncauth_passwd -show *
|
|
pack .f1.l -side left
|
|
pack .f1.e -side left -expand 1 -fill x
|
|
bind .f1.e <Return> launch
|
|
|
|
frame .fu
|
|
label .fu.l -width $wl -anchor w -text "Unix Username:" -relief ridge
|
|
entry .fu.e -width 14 -textvariable unixpw_username
|
|
label .fu.m -anchor w -text "Unix Password:" -relief ridge
|
|
entry .fu.f -textvariable unixpw_passwd -show *
|
|
pack .fu.l -side left
|
|
pack .fu.e .fu.m -side left
|
|
pack .fu.f -side left -expand 1 -fill x
|
|
bind .fu.f <Return> launch
|
|
|
|
frame .f2
|
|
label .f2.l -width $wl -anchor w -text "Proxy/Gateway:" -relief ridge
|
|
entry .f2.e -width $we -textvariable vncproxy
|
|
pack .f2.l -side left
|
|
pack .f2.e -side left -expand 1 -fill x
|
|
bind .f2.e <Return> launch
|
|
|
|
frame .f3
|
|
label .f3.l -width $wl -anchor w -text "Remote SSH Command:" -relief ridge
|
|
entry .f3.e -width $we -textvariable remote_ssh_cmd
|
|
pack .f3.l -side left
|
|
pack .f3.e -side left -expand 1 -fill x
|
|
.f3.l configure -state disabled
|
|
.f3.e configure -state disabled
|
|
bind .f3.e <Return> launch
|
|
|
|
set remote_ssh_cmd_list {.f3.e .f3.l}
|
|
|
|
frame .f4
|
|
radiobutton .f4.ssl -anchor w -variable sshssl_sw -value ssl -command {ssl_ssh_adjust ssl} -text "Use SSL"
|
|
radiobutton .f4.ssh -anchor w -variable sshssl_sw -value ssh -command {ssl_ssh_adjust ssh} -text "Use SSH"
|
|
radiobutton .f4.sshssl -anchor w -variable sshssl_sw -value sshssl -command {ssl_ssh_adjust sshssl} -text "SSH+SSL"
|
|
pack .f4.ssl .f4.ssh .f4.sshssl -side left -fill x
|
|
|
|
set showing_no_encryption 0
|
|
radiobutton .f4.none -anchor w -variable sshssl_sw -value none -command {ssl_ssh_adjust none} -text "None "
|
|
if [disable_encryption] {
|
|
pack .f4.none -side left
|
|
set showing_no_encryption 1
|
|
}
|
|
|
|
global skip_verify_accepted_certs
|
|
set skip_verify_accepted_certs 0
|
|
global anon_dh_detected
|
|
set anon_dh_detected 0
|
|
global vencrypt_detected
|
|
set vencrypt_detected ""
|
|
|
|
global always_verify_ssl
|
|
set always_verify_ssl 1;
|
|
if {[info exists env(SSVNC_NO_VERIFY_ALL)]} {
|
|
set always_verify_ssl 0;
|
|
}
|
|
|
|
if {$uname == "Darwin"} {
|
|
button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert"
|
|
} else {
|
|
button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -padx 3
|
|
}
|
|
checkbutton .f4.always -variable always_verify_ssl -text "Verify All Certs" -command no_certs_tutorial_mesg
|
|
pack .f4.getcert -side right -fill x
|
|
if {[info exists env(SSVNC_NO_VERIFY_ALL_BUTTON)]} {
|
|
set always_verify_ssl 0;
|
|
} else {
|
|
pack .f4.always -side right -fill x
|
|
}
|
|
|
|
if {$ssh_only || $ts_only} {
|
|
ssl_ssh_adjust ssh
|
|
} else {
|
|
ssl_ssh_adjust ssl
|
|
}
|
|
|
|
frame .b
|
|
button .b.help -text "Help" -command help
|
|
button .b.certs -text "Certs ..." -command getcerts
|
|
button .b.opts -text "Options ..." -command set_options
|
|
button .b.load -text "Load" -command {load_profile}
|
|
button .b.save -text "Save" -command {save_profile}
|
|
button .b.conn -text "Connect" -command launch
|
|
button .b.exit -text "Exit" -command {destroy .; exit}
|
|
|
|
|
|
if {$ssh_only || $ts_only} {
|
|
pack .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x
|
|
} else {
|
|
pack .b.certs .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x
|
|
}
|
|
|
|
if {$multientry} {
|
|
if {! $is_windows} {
|
|
if {$ssh_only} {
|
|
pack .l .f0 .f1 .f2 .f3 .b -side top -fill x
|
|
} elseif {$ts_only} {
|
|
pack .l .f0 .f2 .b -side top -fill x
|
|
} else {
|
|
pack .l .f0 .f1 .f2 .f3 .f4 .b -side top -fill x
|
|
}
|
|
} else {
|
|
if {$ssh_only} {
|
|
pack .l .f0 .f2 .f3 .b -side top -fill x
|
|
} elseif {$ts_only} {
|
|
pack .l .f0 .f2 .b -side top -fill x
|
|
} else {
|
|
pack .l .f0 .f2 .f3 .f4 .b -side top -fill x
|
|
}
|
|
}
|
|
} else {
|
|
pack .l .f0 .b -side top -fill x
|
|
}
|
|
if {![info exists env(SSVNC_GUI_CHILD)] || $env(SSVNC_GUI_CHILD) == ""} {
|
|
center_win .
|
|
}
|
|
focus .f0.e
|
|
|
|
wm deiconify .
|
|
|
|
global system_button_face
|
|
set system_button_face ""
|
|
foreach item [.b.help configure -bg] {
|
|
set system_button_face $item
|
|
}
|
|
|
|
if {[info exists env(SSVNC_GUI_CMD)]} {
|
|
set env(SSVNC_GUI_CHILD) 1
|
|
bind . <Control-n> "exec $env(SSVNC_GUI_CMD) &"
|
|
}
|
|
bind . <Control-q> "destroy .; exit"
|
|
bind . <Shift-Escape> "destroy .; exit"
|
|
bind . <Control-s> "launch_shell_only"
|
|
bind . <Control-p> {port_knock_only "" "KNOCK"}
|
|
bind . <Control-P> {port_knock_only "" "FINISH"}
|
|
bind . <Control-l> {load_profile}
|
|
bind . <B3-ButtonRelease> {load_profile}
|
|
|
|
bind . <Control-t> {toggle_tsonly}
|
|
bind . <Control-d> {delete_profile}
|
|
bind . <Shift-B3-ButtonRelease> {toggle_tsonly}
|
|
bind . <Shift-B2-ButtonRelease> {toggle_tsonly}
|
|
bind .l <Shift-ButtonRelease> {toggle_tsonly}
|
|
bind . <Control-h> {toggle_sshonly}
|
|
bind . <Control-T> {to_ssvnc}
|
|
bind . <Control-a> {set_advanced_options}
|
|
bind . <Control-o> {set_options}
|
|
bind . <Control-u> {set_ssvncviewer_options}
|
|
bind . <Control-e> {toggle_no_encryption}
|
|
|
|
global entered_gui_top button_gui_top
|
|
set entered_gui_top 0
|
|
set button_gui_top 0
|
|
bind . <Enter> {set entered_gui_top 1}
|
|
bind .l <ButtonPress> {set button_gui_top 1}
|
|
bind .f0.l <ButtonPress> {set button_gui_top 1}
|
|
|
|
update
|
|
|
|
mac_raise
|
|
|
|
set didload 0
|
|
|
|
for {set i 0} {$i < $argc} {incr i} {
|
|
set item [lindex $argv $i]
|
|
regsub {^--} $item "-" item
|
|
if {$item == "."} {
|
|
;
|
|
} elseif {$item == "-nv"} {
|
|
set always_verify_ssl 0
|
|
} elseif {$item == "-help"} {
|
|
help
|
|
} elseif {$item == "-ssh"} {
|
|
;
|
|
} elseif {$item == "-bigger"} {
|
|
;
|
|
} elseif {$item == "-ts"} {
|
|
;
|
|
} elseif {$item == "-ss"} {
|
|
;
|
|
} elseif {$item == "-ssl"} {
|
|
;
|
|
} elseif {$item == "-tso"} {
|
|
;
|
|
} elseif {$item == "-mycert" || $item == "-cert"} {
|
|
incr i
|
|
} elseif {$item == "-cacert" || $item == "-ca"} {
|
|
incr i
|
|
} elseif {$item == "-crl"} {
|
|
incr i
|
|
} elseif {$item == "-printhelp"} {
|
|
print_help
|
|
exit;
|
|
} elseif {$item != ""} {
|
|
if {[file exists $item] && [file isfile $item]} {
|
|
set didload 1
|
|
load_profile . $item
|
|
} else {
|
|
set ok 0
|
|
set dir [get_profiles_dir]
|
|
set try "$dir/$item"
|
|
foreach try [list $dir/$item $dir/$item.vnc] {
|
|
if {[file exists $try] && [file isfile $try]} {
|
|
load_profile . $try
|
|
set ok 1
|
|
break;
|
|
}
|
|
}
|
|
if {! $ok && [regexp {:[0-9][0-9]*$} $item]} {
|
|
global vncdisplay
|
|
set vncdisplay $item
|
|
set ok 1
|
|
}
|
|
|
|
if {! $ok} {
|
|
if {$ts_only || $ssh_only} {
|
|
global vncdisplay
|
|
set vncdisplay $item
|
|
set ok 1
|
|
}
|
|
}
|
|
if {$ok} {
|
|
update
|
|
set didload 1
|
|
if [info exists env(SSVNC_PROFILE_LOADONLY)] {
|
|
if {$env(SSVNC_PROFILE_LOADONLY) == "1"} {
|
|
set ok 0
|
|
}
|
|
}
|
|
if {$ok} {
|
|
after 750
|
|
launch
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|