summaryrefslogtreecommitdiffstats
path: root/classes/ssl
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2011-11-09 20:00:16 +0100
committerChristian Beier <dontmind@freeshell.org>2011-11-09 20:00:16 +0100
commitfaadd484489efddd182d6d0df43d8ecfdbff29ff (patch)
tree9c098fca3bd1280a2166259650695d172d049aee /classes/ssl
parent7cb0e4a9a95886300268e1bff1e72b4c18f1b762 (diff)
downloadlibtdevnc-faadd484489efddd182d6d0df43d8ecfdbff29ff.tar.gz
libtdevnc-faadd484489efddd182d6d0df43d8ecfdbff29ff.zip
Rename 'classes' dir to 'webclients'.
Diffstat (limited to 'classes/ssl')
-rw-r--r--classes/ssl/Makefile.am2
-rw-r--r--classes/ssl/README338
-rw-r--r--classes/ssl/SignedUltraViewerSSL.jarbin113117 -> 0 bytes
-rw-r--r--classes/ssl/SignedVncViewer.jarbin89208 -> 0 bytes
-rw-r--r--classes/ssl/UltraViewerSSL.jarbin110040 -> 0 bytes
-rw-r--r--classes/ssl/VncViewer.jarbin86228 -> 0 bytes
-rw-r--r--classes/ssl/index.vnc26
-rwxr-xr-xclasses/ssl/onetimekey65
-rw-r--r--classes/ssl/proxy.vnc73
-rwxr-xr-xclasses/ssl/ss_vncviewer3676
-rw-r--r--classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch111
-rw-r--r--classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch2600
-rw-r--r--classes/ssl/ultra.vnc28
-rw-r--r--classes/ssl/ultraproxy.vnc28
-rw-r--r--classes/ssl/ultrasigned.vnc28
-rw-r--r--classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch5494
16 files changed, 0 insertions, 12469 deletions
diff --git a/classes/ssl/Makefile.am b/classes/ssl/Makefile.am
deleted file mode 100644
index fd1c201..0000000
--- a/classes/ssl/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-EXTRA_DIST=VncViewer.jar index.vnc SignedVncViewer.jar proxy.vnc README ss_vncviewer onetimekey UltraViewerSSL.jar SignedUltraViewerSSL.jar ultra.vnc ultrasigned.vnc ultraproxy.vnc
-
diff --git a/classes/ssl/README b/classes/ssl/README
deleted file mode 100644
index b244cf1..0000000
--- a/classes/ssl/README
+++ /dev/null
@@ -1,338 +0,0 @@
-This directory contains a patched Java applet VNC viewer that is SSL
-enabled.
-
-The patches in the *.patch files are relative to the source tarball:
-
- tightvnc-1.3dev7_javasrc.tar.gz
-
-currently (4/06) available here:
-
- http://prdownloads.sourceforge.net/vnc-tight/tightvnc-1.3dev7_javasrc.tar.gz?download
-
-It also includes some simple patches to:
-
- - fix richcursor colors
-
- - make the Java Applet cursor (not the cursor drawn to the canvas
- framebuffer) invisible when it is inside the canvas.
-
- - allow Tab (and some other) keystrokes to be sent to the vnc
- server instead of doing widget traversal.
-
-
-This SSL applet should work with any VNC viewer that has an SSL tunnel in
-front of it. It has been tested on x11vnc and using the stunnel tunnel
-to other VNC servers.
-
-By default this Vnc Viewer will only do SSL. To do unencrypted traffic
-see the "DisableSSL" applet parameter (e.g. set it to Yes in index.vnc).
-
-Proxies: they are a general problem with java socket applets (a socket
-connection does not go through the proxy). See the info in the proxy.vnc
-file for a workaround. It uses SignedVncViewer.jar which is simply
-a signed version of VncViewer.jar. The basic idea is the user clicks
-"Yes" to trust the applet and then it can connect directly to the proxy
-and issue a CONNECT request.
-
-This applet has been tested on versions 1.4.2 and 1.5.0 of the Sun
-Java plugin. It may not work on older releases or different vendor VM's.
-Send full Java Console output for failures.
-
----------------------------------------------------------------
-Tips:
-
-When doing single-port proxy connections (e.g. both VNC and HTTPS
-thru port 5900) it helps to move through the 'do you trust this site'
-dialogs quickly. x11vnc has to wait to see if the traffic is VNC or
-HTTP and this can cause timeouts if you don't move thru them quickly.
-
-You may have to restart your browser completely if it gets into a
-weird state. For one case we saw the JVM requesting VncViewer.class
-even when no such file exists.
-
-
----------------------------------------------------------------
-Extras:
-
-ss_vncviewer (not Java):
-
- Wrapper script for native VNC viewer to connect to x11vnc in
- SSL mode. Script launches stunnel(8) and then connects to it
- via localhost which in turn is then redirected to x11vnc via an
- SSL tunnel. stunnel(8) must be installed and available in PATH.
-
-
-Running Java SSL VncViewer from the command line:
-
- From this directory:
-
- java -cp ./VncViewer.jar VncViewer HOST <thehost> PORT <theport>
-
- substitute <thehost> and <theport> with the actual values.
- You can add any other parameters, e.g.: ignoreProxy yes
-
----------------------------------------------------------------
-UltraVNC:
-
-The UltraVNC java viewer has also been patched to support SSL. Various
-bugs in the UltraVNC java viewer were also fixed. This viewer can be
-useful because is support UltraVNC filetransfer, and so it works on
-Unix, etc.
-
-UltraViewerSSL.jar
-SignedUltraViewerSSL.jar
-ultra.vnc
-ultraproxy.vnc
-ultravnc-102-JavaViewer-ssl-etc.patch
-
----------------------------------------------------------------
-Applet Parameters:
-
-Some additional applet parameters can be set via the URL, e.g.
-
- http://host:5800/?param=value
- http://host:5800/ultra.vnc?param=value
- https://host:5900/ultra.vnc?param=value
-
-etc. If running java from command line as show above, it comes
-in as java ... VncViewer param value ...
-
-There is a limitation with libvncserver that param and value can
-only be alphanumeric, underscore, "+" (for space), or "."
-
-We have added some applet parameters to the stock VNC java
-viewers. Here are the applet parameters:
-
-Both TightVNC and UltraVNC Java viewers:
-
- HOST
- string, default: none.
- The Hostname to connect to.
-
- PORT
- number, default: 0
- The VNC server port to connect to.
-
- Open New Window
- yes/no, default: no
- Run applet in separate frame.
-
- Show Controls
- yes/no, default: yes
- Show Controls button panel.
-
- Show Offline Desktop
- yes/no, default: no
- Do we continue showing desktop on remote disconnect?
-
- Defer screen updates
- number, default: 20
- Milliseconds delay
-
- Defer cursor updates
- number, default: 10
- Milliseconds delay
-
- Defer update requests
- number, default: 50
- Milliseconds delay
-
- PASSWORD
- string, default: none
- VNC session password in plain text.
-
- ENCPASSWORD
- string, default: none
- VNC session password in encrypted in DES with KNOWN FIXED
- key. It is a hex string. This is like the ~/.vnc/passwd format.
-
-
- The following are added by x11vnc and/or ssvnc project
-
- VNCSERVERPORT
- number, default: 0
- Like PORT, but if there is a firewall this is the Actual VNC
- server port. PORT might be a redir port on the firewall.
-
- DisableSSL
- yes/no, default: no
- Do unencrypted connection, no SSL.
-
- httpsPort
- number, default: none
- When checking for proxy, use this at the url port number.
-
- CONNECT
- string, default: none
- Sets to host:port for the CONNECT line to a Web proxy.
- The Web proxy should connect us to it.
-
- GET
- yes/no, default: no
- Set to do a special HTTP GET (/request.https.vnc.connection)
- to the vnc server that will cause it to switch to VNC instead.
- This is to speedup/make more robust, the single port HTTPS and VNC
- mode of x11vnc (e.g. both services thru port 5900, etc)
-
- urlPrefix
- string, default: none
- set to a string that will be prefixed to all URL's when contacting
- the VNC server. Idea is a special proxy will use this to indicate
- internal hostname, etc.
-
- oneTimeKey
- string, default: none
- set a special hex "key" to correspond to an SSL X.509 cert+key.
- See the 'onetimekey' helper script. Can also be PROMPT to prompt
- the user to paste the hex key string in.
-
- This provides a Client-Side cert+key that the client will use to
- authenticate itself by SSL To the VNC Server.
-
- This is to try to work around the problem that the Java applet
- cannot keep an SSL keystore on disk, etc. E.g. if they log
- into an HTTPS website via password they are authenticated and
- encrypted, then the website can safely put oneTimeKey=... on the
- URL. The Vncviewer authenticates the VNC server with this key.
-
- Note that there is currently a problem in that if x11vnc requires
- Client Certificates the user cannot download the index.vnc HTML
- and VncViewer.jar from the same x11vnc. Those need to come from
- a different x11vnc or from a web server.
-
- Note that the HTTPS website can also put the VNC Password
- (e.g. a temporary/one-time one) in the parameter PASSWORD.
- The Java Applet will automatically supply this VNC password
- instead of prompting.
-
- serverCert
- string, default: none
- set a special hex "cert" to correspond to an SSL X.509 cert
- See the 'onetimekey -certonly' helper script.
-
- This provides a Server-Side cert that the client will authenticate
- the VNC Server against by SSL.
-
- This is to try to work around the problem that the Java applet
- cannot keep an SSL keystore on disk, etc. E.g. if they log
- into an HTTPS website via password they are authenticated and
- encrypted, then the website can safely put serverCert=... on the
- URL.
-
- Of course the VNC Server is sending this string to the Java
- Applet, so this is only reasonable security if the VNC Viewer
- already trusts the HTTPS retrieval of the URL + serverCert param
- that it gets. This should be done over HTTPS not HTTP.
-
- proxyHost
- string, default: none
- Do not try to guess the proxy's hostname, use the value in
- proxyHost. Does not imply forceProxy (below.)
-
- proxyPort
- string, default: none
- Do not try to guess the proxy's port number, use the value in
- proxyPort. Does not imply forceProxy (below.)
-
- forceProxy
- yes/no, default: no
- Assume there is a proxy and force its use.
-
- If a string other than "yes" or "no" is given, it implies "yes"
- and uses the string for proxyHost and proxyPort (see above).
- In this case the string must be of the form "hostname+port".
- Note that it is "+" and not ":" before the port number.
-
- ignoreProxy
- yes/no, default: no
- Don't check for a proxy, assume there is none.
-
- trustAllVncCerts
- yes/no, default: no
- Automatically trust any cert received from the VNC server
- (obviously this could be dangerous and lead to man in the
- middle attack). Do not ask the user to verify any of these
- certs from the VNC server.
-
- trustUrlVncCert
- yes/no, default: no
- Automatically trust any cert that the web browsers has accepted.
- E.g. the user said "Yes" or "Continue" to a web browser dialog
- regarding a certificate. If we get the same cert (chain) from
- the VNC server we trust it without prompting the user.
-
- debugCerts
- yes/no, default: no
- Print out every cert in the Server, TrustUrl, TrustAll chains.
-
-
-TightVNC Java viewer only:
-
- Offer Relogin
- yes/no, default: yes
- "Offer Relogin" set to "No" disables "Login again"
-
- SocketFactory
- string, default: none
- set Java Socket class factory.
-
-UltraVNC Java viewer only:
-
- None.
-
- The following are added by x11vnc and/or ssvnc project
-
- ftpDropDown
- string, default: none
- Sets the file transfer "drives" dropdown to the "." separated
- list. Use "+" for space. The default is
-
- My+Documents.Desktop.Home
-
- for 3 entries in the dropdown in addition to the "drives"
- (e.g. C:\) These items should be expanded properly by the VNC
- Server. x11vnc will prepend $HOME to them, which is normally
- what one wants. To include a "/" use "_2F_". Another example:
-
- Home.Desktop.bin_2F_linux
-
- If an item is prefixed with "TOP_" then the item is inserted at
- the top of the drop down rather than being appended to the end.
- E.g. to try to initially load the user homedir instead of /:
-
- TOP_Home.My+Documents.Desktop
-
- If ftpDropDown is set to the empty string, "", then no special
- locations, [Desktop] etc., are placed in the drop down. Only the
- ultravnc "drives" will appear.
-
- ftpOnly
- yes/no, default: no
- The VNC viewer only shows the filetransfer panel, no desktop
- is displayed.
-
- graftFtp
- yes/no, default: no
- As ftpOnly, the VNC viewer only shows the filetransfer panel,
- no desktop is displayed, however it is "grafted" onto an existing
- SSVNC unix vncviewer. The special SSVNC vncviewer merges the two
- channels.
-
- dsmActive
- yes/no, default: no
- Special usage mode with the SSVNC unix vncviewer. The UltraVNC
- DSM encryption is active. Foolishly, UltraVNC DSM encryption
- *MODIFIES* the VNC protocol when active (it is not a pure tunnel).
- This option indicates to modify the VNC protocol to make this work.
- Usually only used with graftFtp and SSVNC unix vncviewer.
-
- delayAuthPanel
- yes/no, default: no
- This is another special usage mode with the SSVNC unix vncviewer.
- A login panel is delayed (not shown at startup.) Could be useful
- for non SSVNC usage too.
-
- ignoreMSLogonCheck
- yes/no, default: no
- Similar to delayAuthPanel, do not put up a popup asking for
- Windows username, etc.
diff --git a/classes/ssl/SignedUltraViewerSSL.jar b/classes/ssl/SignedUltraViewerSSL.jar
deleted file mode 100644
index 6c18737..0000000
--- a/classes/ssl/SignedUltraViewerSSL.jar
+++ /dev/null
Binary files differ
diff --git a/classes/ssl/SignedVncViewer.jar b/classes/ssl/SignedVncViewer.jar
deleted file mode 100644
index 95c0b0b..0000000
--- a/classes/ssl/SignedVncViewer.jar
+++ /dev/null
Binary files differ
diff --git a/classes/ssl/UltraViewerSSL.jar b/classes/ssl/UltraViewerSSL.jar
deleted file mode 100644
index 45259fd..0000000
--- a/classes/ssl/UltraViewerSSL.jar
+++ /dev/null
Binary files differ
diff --git a/classes/ssl/VncViewer.jar b/classes/ssl/VncViewer.jar
deleted file mode 100644
index 9453c6f..0000000
--- a/classes/ssl/VncViewer.jar
+++ /dev/null
Binary files differ
diff --git a/classes/ssl/index.vnc b/classes/ssl/index.vnc
deleted file mode 100644
index ec520dc..0000000
--- a/classes/ssl/index.vnc
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- index.vnc - default HTML page for TightVNC Java viewer applet, to be
- used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
- Xvnc will substitute the following variables when preceded by a dollar:
- USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
- PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
- HTML page.
-
- NOTE: the $PARAMS variable is not supported by the standard VNC, so
- make sure you have TightVNC on the server side, if you're using this
- variable.
--->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
- WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name="Open New Window" value=yes>
-$PARAMS
-</APPLET>
-<BR>
-<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
-</HTML>
diff --git a/classes/ssl/onetimekey b/classes/ssl/onetimekey
deleted file mode 100755
index bf57c8f..0000000
--- a/classes/ssl/onetimekey
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/sh
-#
-# usage: onetimekey path/to/mycert.pem
-# onetimekey -certonly path/to/mycert.pem
-#
-# Takes an openssl cert+key pem file and turns into a long string
-# for the x11vnc SSL VNC Java Viewer.
-#
-# The Java applet URL parameter can be oneTimeKey=<str> where str is
-# the output of this program, or can be oneTimeKey=PROMPT in which
-# case the applet will ask you to paste in the string.
-#
-# The problem trying to be solved here is it is difficult to get
-# the Java applet to have or use a keystore with the key saved
-# in it. Also, as the name implies, an HTTPS server can create
-# a one time key to send to the applet (the user has already
-# logged in via password to the HTTPS server).
-#
-# Note oneTimeKey is to provide a CLIENT Certificate for the viewer
-# to authenticate itself to the VNC Server.
-#
-# There is also the serverCert=<str> Applet parameter. This is
-# a cert to authenticate the VNC server against. To create that
-# string with this tool specify -certonly as the first argument.
-
-certonly=""
-if [ "X$1" = "X-certonly" ]; then
- shift
- certonly=1
-fi
-
-in=$1
-der=/tmp/1time$$.der
-touch $der
-chmod 600 $der
-
-openssl pkcs8 -topk8 -nocrypt -in "$in" -out "$der" -outform der
-
-pbinhex=/tmp/pbinhex.$$
-cat > $pbinhex <<END
-#!/usr/bin/perl
-
-\$str = '';
-while (1) {
- \$c = getc(STDIN);
- last if \$c eq '';
- \$str .= sprintf("%02x", unpack("C", \$c));
-}
-
-print "\$str\n";
-END
-
-chmod 700 $pbinhex
-
-str1=`$pbinhex < "$der"`
-rm -f "$der"
-
-n=`grep -n 'BEGIN CERTIFICATE' $in | awk -F: '{print $1}' | head -1`
-str2=`tail +$n $in | $pbinhex`
-if [ "X$certonly" = "X1" ]; then
- echo "$str2"
-else
- echo "$str1,$str2"
-fi
-rm -f $pbinhex
diff --git a/classes/ssl/proxy.vnc b/classes/ssl/proxy.vnc
deleted file mode 100644
index 6d3ab3d..0000000
--- a/classes/ssl/proxy.vnc
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
- index.vnc - default HTML page for TightVNC Java viewer applet, to be
- used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
- Xvnc will substitute the following variables when preceded by a dollar:
- USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
- PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
- HTML page.
-
- NOTE: the $PARAMS variable is not supported by the standard VNC, so
- make sure you have TightVNC on the server side, if you're using this
- variable.
--->
-
-<!--
-The idea behind using the signed applet in SignedVncViewer.jar for
-firewall proxies:
-
-Java socket applets and http proxies do not get along well.
-
-Java security allows the applet to connect back via a socket to the
-originating host, but the browser/plugin Proxy settings are not used for
-socket connections (only http and the like). So the socket connection
-fails in the proxy environment.
-
-The applet is not allowed to open a socket connection to the proxy (since
-that would let it connect to just about any host, e.g. CONNECT method).
-
-This is indpendent of SSL but of course fails for that socket connection
-as well. I.e. this is a problem for non-SSL VNC Viewers as well.
-
-Solution? Sign the applet and have the user click on "Yes" that they
-fully trust the applet. Then the applet can connect to any host via
-sockets, in particular the proxy. It next issues the request
-
- CONNECT host:port HTTP/1.1
- Host: host:port
-
-and if the proxy supports the CONNECT method we are finally connected to
-the VNC server.
-
-For SSL connections, SSL is layered on top of this socket. However note
-this scheme will work for non-SSL applet proxy tunnelling as well.
-
-It should be able to get non-SSL VNC connections to work via GET
-command but that has not been done yet.
-
-Note that some proxies only allow CONNECT to only these the ports 443
-(HTTPS) and 563 (SNEWS). So you would have to run the VNC server on
-those ports.
-
-SignedVncViewer.jar is just a signed version of VncViewer.jar
-
-The URL to use for this file: https://host:port/proxy.vnc
-
-Note VNCSERVERPORT, we assume $PARAMS will have the correct PORT setting
-(e.g. 563), not the one libvncserver puts in....
-
--->
-
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=SignedVncViewer.jar
- WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=VNCSERVERPORT value=$PORT>
-<param name="Open New Window" value=yes>
-$PARAMS
-</APPLET>
-<BR>
-<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
-</HTML>
diff --git a/classes/ssl/ss_vncviewer b/classes/ssl/ss_vncviewer
deleted file mode 100755
index 7e793ff..0000000
--- a/classes/ssl/ss_vncviewer
+++ /dev/null
@@ -1,3676 +0,0 @@
-#!/bin/sh
-#
-# ss_vncviewer: wrapper for vncviewer to use an stunnel SSL tunnel
-# or an SSH tunnel.
-#
-# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com>
-#
-# ss_vncviewer is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# ss_vncviewer is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with ss_vncviewer; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-# or see <http://www.gnu.org/licenses/>.
-#
-#
-# You must have stunnel(8) installed on the system and in your PATH
-# (however, see the -ssh option below, in which case you will need ssh(1)
-# installed) Note: stunnel is usually installed in an "sbin" subdirectory.
-#
-# You should have "x11vnc -ssl ..." or "x11vnc -stunnel ..."
-# already running as the VNC server on the remote machine.
-# (or use stunnel on the server side for any other VNC server)
-#
-#
-# Usage: ss_vncviewer [cert-args] host:display <vncviewer-args>
-#
-# e.g.: ss_vncviewer snoopy:0
-# ss_vncviewer snoopy:0 -encodings "copyrect tight zrle hextile"
-#
-# [cert-args] can be:
-#
-# -verify /path/to/cacert.pem
-# -mycert /path/to/mycert.pem
-# -crl /path/to/my_crl.pem (or directory)
-# -proxy host:port
-#
-# -verify specifies a CA cert PEM file (or a self-signed one) for
-# authenticating the VNC server.
-#
-# -mycert specifies this client's cert+key PEM file for the VNC server to
-# authenticate this client.
-#
-# -proxy try host:port as a Web proxy to use the CONNECT method
-# to reach the VNC server (e.g. your firewall requires a proxy).
-#
-# For the "double proxy" case use -proxy host1:port1,host2:port2
-# (the first CONNECT is done through host1:port1 to host2:port2
-# and then a 2nd CONNECT to the destination VNC server.)
-#
-# Use socks://host:port, socks4://host:port, or socks5://host,port
-# to force usage of a SOCKS proxy. Also repeater://host:port and
-# sslrepeater://host:port.
-#
-# -showcert Only fetch the certificate using the 'openssl s_client'
-# command (openssl(1) must in installed). On ssvnc 1.0.27 and
-# later the bundled command 'ultravnc_dsm_helper' is used.
-#
-# See http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca for details on
-# SSL certificates with VNC.
-#
-# A few other args (not related to SSL and certs):
-#
-# -2nd Run the vncviewer a 2nd time if the first connections fails.
-#
-# -ssh Use ssh instead of stunnel SSL. ssh(1) must be installed and you
-# must be able to log into the remote machine via ssh.
-#
-# In this case "host:display" may be of the form "user@host:display"
-# where "user@host" is used for the ssh login (see ssh(1) manpage).
-#
-# If -proxy is supplied it can be of the forms: "gwhost" "gwhost:port"
-# "user@gwhost" or "user@gwhost:port". "gwhost" is an incoming ssh
-# gateway machine (the VNC server is not running there), an ssh -L
-# redir is used to "host" in "host:display" from "gwhost". Any "user@"
-# part must be in the -proxy string (not in "host:display").
-#
-# Under -proxy use "gwhost:port" if connecting to any ssh port
-# other than the default (22). (even for the non-gateway case,
-# -proxy must be used to specify a non-standard ssh port)
-#
-# A "double ssh" can be specified via a -proxy string with the two
-# hosts separated by a comma:
-#
-# [user1@]host1[:port1],[user2@]host2[:port2]
-#
-# in which case a ssh to host1 and thru it via a -L redir a 2nd
-# ssh is established to host2.
-#
-# Examples:
-#
-# ss_vncviewer -ssh bob@bobs-home.net:0
-# ss_vncviewer -ssh -sshcmd 'x11vnc -localhost' bob@bobs-home.net:0
-#
-# ss_vncviewer -ssh -proxy fred@mygate.com:2022 mymachine:0
-# ss_vncviewer -ssh -proxy bob@bobs-home.net:2222 localhost:0
-#
-# ss_vncviewer -ssh -proxy fred@gw-host,fred@peecee localhost:0
-#
-# -sshcmd cmd Run "cmd" via ssh instead of the default "sleep 15"
-# e.g. -sshcmd 'x11vnc -display :0 -localhost -rfbport 5900'
-#
-# -sshargs "args" pass "args" to the ssh process, e.g. -L/-R port redirs.
-#
-# -sshssl Tunnel the SSL connection thru a SSH connection. The tunnel as
-# under -ssh is set up and the SSL connection goes thru it. Use
-# this if you want to have and end-to-end SSL connection but must
-# go thru a SSH gateway host (e.g. not the vnc server). Or use
-# this if you need to tunnel additional services via -R and -L
-# (see -sshargs above).
-#
-# ss_vncviewer -sshssl -proxy fred@mygate.com mymachine:0
-#
-# -listen (or -reverse) set up a reverse connection.
-#
-# -alpha turn on cursor alphablending hack if you are using the
-# enhanced tightvnc vncviewer.
-#
-# -grab turn on XGrabServer hack if you are using the enhanced tightvnc
-# vncviewer (e.g. for fullscreen mode in some windowmanagers like
-# fvwm that do not otherwise work in fullscreen mode)
-#
-#
-# set VNCVIEWERCMD to whatever vncviewer command you want to use.
-#
-VNCIPCMD=${VNCVIEWERCMD:-vncip}
-VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
-if [ "X$SSVNC_TURBOVNC" != "X" ]; then
- if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then
- :
- else
- if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then
- VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc"
- fi
- fi
-fi
-#
-# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc.
-#
-
-# turn on verbose debugging output
-if [ "X$SS_DEBUG" != "X" -a "X$SS_DEBUG" != "X0" ]; then
- set -xv
-fi
-
-PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH
-
-localhost="localhost"
-if uname | grep Darwin >/dev/null; then
- localhost="127.0.0.1"
-fi
-
-# work out which stunnel to use (debian installs as stunnel4)
-stunnel_set_here=""
-if [ "X$STUNNEL" = "X" ]; then
- check_stunnel=1
- if [ "X$SSVNC_BASEDIRNAME" != "X" ]; then
- if [ -x "$SSVNC_BASEDIRNAME/stunnel" ]; then
- type stunnel > /dev/null 2>&1
- if [ $? = 0 ]; then
- # found ours
- STUNNEL=stunnel
- check_stunnel=0
- fi
- fi
- fi
- if [ "X$check_stunnel" = "X1" ]; then
- type stunnel4 > /dev/null 2>&1
- if [ $? = 0 ]; then
- STUNNEL=stunnel4
- else
- STUNNEL=stunnel
- fi
- fi
- stunnel_set_here=1
-fi
-
-help() {
- tail -n +2 "$0" | sed -e '/^$/ q'
-}
-
-secondtry=""
-gotalpha=""
-use_ssh=""
-use_sshssl=""
-direct_connect=""
-ssh_sleep=15
-
-# sleep longer in -listen mode:
-if echo "$*" | grep '.*-listen' > /dev/null; then
- ssh_sleep=1800
-fi
-
-
-ssh_cmd=""
-# env override of ssh_cmd:
-if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then
- ssh_cmd="$SS_VNCVIEWER_SSH_CMD"
-fi
-
-ssh_args=""
-showcert=""
-reverse=""
-
-ciphers=""
-anondh="ALL:RC4+RSA:+SSLv2:@STRENGTH"
-anondh_set=""
-stunnel_debug="6"
-if [ "X$SS_DEBUG" != "X" -o "X$SSVNC_VENCRYPT_DEBUG" != "X" -o "X$SSVNC_STUNNEL_DEBUG" != "X" ]; then
- stunnel_debug="7"
-fi
-
-if [ "X$1" = "X-viewerflavor" ]; then
- # special case, try to guess which viewer:
- #
- if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
- echo "unknown"
- exit 0
- fi
- if echo "$VNCVIEWERCMD" | grep -i chicken.of > /dev/null; then
- echo "cotvnc"
- exit 0
- fi
- if echo "$VNCVIEWERCMD" | grep -i ultra > /dev/null; then
- echo "ultravnc"
- exit 0
- fi
- # OK, run it for help output...
- str=`$VNCVIEWERCMD -h 2>&1 | head -n 5`
- if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then
- echo "tightvnc"
- elif echo "$str" | grep -i 'VNC viewer version 3' > /dev/null; then
- echo "realvnc3"
- elif echo "$str" | grep -i 'VNC viewer .*Edition 4' > /dev/null; then
- echo "realvnc4"
- elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then
- echo "realvnc4"
- else
- echo "unknown"
- fi
- exit 0
-fi
-if [ "X$1" = "X-viewerhelp" ]; then
- $VNCVIEWERCMD -h 2>&1
- exit 0
-fi
-
-# grab our cmdline options:
-while [ "X$1" != "X" ]
-do
- case $1 in
- "-verify") shift; verify="$1"
- ;;
- "-mycert") shift; mycert="$1"
- ;;
- "-crl") shift; crl="$1"
- ;;
- "-proxy") shift; proxy="$1"
- ;;
- "-ssh") use_ssh=1
- ;;
- "-sshssl") use_ssh=1
- use_sshssl=1
- ;;
- "-sshcmd") shift; ssh_cmd="$1"
- ;;
- "-sshargs") shift; ssh_args="$1"
- ;;
- "-anondh") ciphers="ciphers=$anondh"
- ULTRAVNC_DSM_HELPER_SHOWCERT_ADH=1
- export ULTRAVNC_DSM_HELPER_SHOWCERT_ADH
- anondh_set=1
- ;;
- "-ciphers") shift; ciphers="ciphers=$1"
- ;;
- "-alpha") gotalpha=1
- ;;
- "-showcert") showcert=1
- ;;
- "-listen") reverse=1
- ;;
- "-reverse") reverse=1
- ;;
- "-2nd") secondtry=1
- ;;
- "-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER
- ;;
- "-x11cursor") VNCVIEWER_X11CURSOR=1; export VNCVIEWER_X11CURSOR
- ;;
- "-rawlocal") VNCVIEWER_RAWLOCAL=1; export VNCVIEWER_RAWLOCAL
- ;;
- "-scale") shift; SSVNC_SCALE="$1"; export SSVNC_SCALE
- ;;
- "-onelisten") SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
- ;;
- "-sendclipboard") VNCVIEWER_SEND_CLIPBOARD=1; export VNCVIEWER_SEND_CLIPBOARD
- ;;
- "-sendalways") VNCVIEWER_SEND_ALWAYS=1; export VNCVIEWER_SEND_ALWAYS
- ;;
- "-recvtext") shift; VNCVIEWER_RECV_TEXT="$1"; export VNCVIEWER_RECV_TEXT
- ;;
- "-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE
- ;;
- "-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS
- ;;
- "-ssvnc_extra_opts") shift; VNCVIEWERCMD_EXTRA_OPTS="$1"; export VNCVIEWERCMD_EXTRA_OPTS
- ;;
- "-rfbversion") shift; VNCVIEWER_RFBVERSION="$1"; export VNCVIEWER_RFBVERSION
- ;;
- "-nobell") VNCVIEWER_NOBELL=1; export VNCVIEWER_NOBELL
- ;;
- "-popupfix") VNCVIEWER_POPUP_FIX=1; export VNCVIEWER_POPUP_FIX
- ;;
- "-realvnc4") VNCVIEWER_IS_REALVNC4=1; export VNCVIEWER_IS_REALVNC4
- ;;
- "-h"*) help; exit 0
- ;;
- "--h"*) help; exit 0
- ;;
- *) break
- ;;
- esac
- shift
-done
-
-# maxconn is something we added to stunnel, this disables it:
-if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then
- STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
-elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
- STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
-elif [ "X$reverse" != "X" ]; then
- STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
-else
- # new way (our patches). other than the above, we set these:
- if [ "X$SKIP_STUNNEL_ONCE" = "X" ]; then
- STUNNEL_ONCE=1; export STUNNEL_ONCE
- fi
- if [ "X$SKIP_STUNNEL_MAX_CLIENTS" = "X" ]; then
- STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
- fi
-fi
-# always set this one:
-if [ "X$SKIP_STUNNEL_NO_SYSLOG" = "X" ]; then
- STUNNEL_NO_SYSLOG=1; export STUNNEL_NO_SYSLOG
-fi
-
-# this is the -t ssh option (gives better keyboard response thru SSH tunnel)
-targ="-t"
-if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then
- targ=""
-fi
-
-# set the alpha blending env. hack:
-if [ "X$gotalpha" = "X1" ]; then
- VNCVIEWER_ALPHABLEND=1
- export VNCVIEWER_ALPHABLEND
-else
- NO_ALPHABLEND=1
- export NO_ALPHABLEND
-fi
-
-if [ "X$reverse" != "X" ]; then
- ssh_sleep=1800
- if [ "X$proxy" != "X" ]; then
- # check proxy usage under reverse connection:
- if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then
- echo ""
- if echo "$proxy" | egrep -i "(repeater|vencrypt)://" > /dev/null; then
- :
- else
- echo "*Warning*: SSL -listen and a Web proxy does not make sense."
- sleep 2
- fi
- elif echo "$proxy" | grep "," > /dev/null; then
- :
- else
- echo ""
- echo "*Warning*: -listen and a single proxy/gateway does not make sense."
- sleep 2
- fi
-
- # we now try to PPROXY_LOOP_THYSELF, set this var to disable that.
- #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
- fi
-fi
-if [ "X$ssh_cmd" = "X" ]; then
- # if no remote ssh cmd, sleep a bit:
- ssh_cmd="sleep $ssh_sleep"
-fi
-
-# this should be a host:display:
-#
-orig="$1"
-shift
-
-dL="-L"
-if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
- dL="-h"
-fi
-
-have_uvnc_dsm_helper_showcert=""
-if [ "X$showcert" = "X1" -a "X$SSVNC_USE_S_CLIENT" = "X" -a "X$reverse" = "X" ]; then
- if type ultravnc_dsm_helper >/dev/null 2>&1; then
- if ultravnc_dsm_helper -help 2>&1 | grep -w showcert >/dev/null; then
- have_uvnc_dsm_helper_showcert=1
- fi
- fi
-fi
-have_uvnc_dsm_helper_ipv6=""
-if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- if type ultravnc_dsm_helper >/dev/null 2>&1; then
- if ultravnc_dsm_helper -help 2>&1 | grep -iw ipv6 >/dev/null; then
- have_uvnc_dsm_helper_ipv6=1
- fi
- fi
-fi
-
-rchk() {
- # a kludge to set $RANDOM if we are not bash:
- if [ "X$BASH_VERSION" = "X" ]; then
- RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'`
- fi
-}
-rchk
-
-# a portable, but not absolutely safe, tmp file creator
-mytmp() {
- tf=$1
- if type mktemp > /dev/null 2>&1; then
- # if we have mktemp(1), use it:
- tf2="$tf.XXXXXX"
- tf2=`mktemp "$tf2"`
- if [ "X$tf2" != "X" -a -f "$tf2" ]; then
- if [ "X$DEBUG_MKTEMP" != "X" ]; then
- echo "mytmp-mktemp: $tf2" 1>&2
- fi
- echo "$tf2"
- return
- fi
- fi
- # fallback to multiple cmds:
- rm -rf "$tf" || exit 1
- if [ -d "$tf" ]; then
- echo "tmp file $tf still exists as a directory."
- exit 1
- elif [ $dL "$tf" ]; then
- echo "tmp file $tf still exists as a symlink."
- exit 1
- elif [ -f "$tf" ]; then
- echo "tmp file $tf still exists."
- exit 1
- fi
- touch "$tf" || exit 1
- chmod 600 "$tf" || exit 1
- rchk
- if [ "X$DEBUG_MKTEMP" != "X" ]; then
- echo "mytmp-touch: $tf" 1>&2
- fi
- echo "$tf"
-}
-
-# set up special case of ultravnc single click III mode:
-if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then
- pstr=`echo "$proxy" | sed -e 's,sslrepeater://,,'`
- pstr1=`echo "$pstr" | sed -e 's/+.*$//'`
- pstr2=`echo "$pstr" | sed -e 's/^[^+]*+//'`
- SSVNC_REPEATER="SCIII=$pstr2"; export SSVNC_REPEATER
- orig=$pstr1
- echo
- echo "reset: SSVNC_REPEATER=$SSVNC_REPEATER orig=$orig proxy=''"
- proxy=""
-fi
-if echo "$proxy" | egrep "vencrypt://" > /dev/null; then
- vtmp="/tmp/ss_handshake${RANDOM}.$$.txt"
- vtmp=`mytmp "$vtmp"`
- SSVNC_PREDIGESTED_HANDSHAKE="$vtmp"
- export SSVNC_PREDIGESTED_HANDSHAKE
- if [ "X$SSVNC_USE_OURS" = "X" ]; then
- NEED_VENCRYPT_VIEWER_BRIDGE=1
- fi
-fi
-if [ "X$SSVNC_USE_OURS" = "X" ]; then
- VNCVIEWERCMD_EXTRA_OPTS=""
-fi
-
-
-# check -ssh and -mycert/-verify conflict:
-if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then
- if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then
- echo "-mycert and -verify cannot be used in -ssh mode"
- exit 1
- fi
-fi
-
-# direct mode Vnc:// means show no warnings.
-# direct mode vnc:// will show warnings.
-if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then
- SSVNC_NO_ENC_WARN=1
- export SSVNC_NO_ENC_WARN
- orig=`echo "$orig" | sed -e 's/^...:/vnc:/'`
-fi
-
-# interprest the pseudo URL proto:// strings:
-if echo "$orig" | grep '^vnc://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vnc://,,'`
- verify=""
- mycert=""
- crl=""
- use_ssh=""
- use_sshssl=""
- direct_connect=1
-elif echo "$orig" | grep '^vncs://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vncs://,,'`
-elif echo "$orig" | grep '^vncssl://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vncssl://,,'`
-elif echo "$orig" | grep '^vnc+ssl://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vnc.ssl://,,'`
-elif echo "$orig" | grep '^vncssh://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vncssh://,,'`
- use_ssh=1
-elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then
- orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'`
- use_ssh=1
-fi
-
-if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- verify=""
- mycert=""
- crl=""
- use_ssh=""
- use_sshssl=""
- direct_connect=1
- if echo "$SSVNC_ULTRA_DSM" | grep 'noultra:' > /dev/null; then
- SSVNC_NO_ULTRA_DSM=1; export SSVNC_NO_ULTRA_DSM
- fi
-fi
-
-# rsh mode is an internal/secret thing only I use.
-rsh=""
-if echo "$orig" | grep '^rsh://' > /dev/null; then
- use_ssh=1
- rsh=1
- orig=`echo "$orig" | sed -e 's,rsh://,,'`
-elif echo "$orig" | grep '^rsh:' > /dev/null; then
- use_ssh=1
- rsh=1
- orig=`echo "$orig" | sed -e 's,rsh:,,'`
-fi
-
-# play around with host:display port:
-if echo "$orig" | grep ':[0-9][0-9]*$' > /dev/null; then
- :
-else
- # add or assume :0 if no ':'
- if [ "X$reverse" = "X" ]; then
- orig="$orig:0"
- elif [ "X$orig" = "X" ]; then
- orig=":0"
- fi
-fi
-
-# extract host and disp number:
-
-# try to see if it is ipv6 address:
-ipv6=0
-if echo "$orig" | grep '\[' > /dev/null; then
- # ipv6 [fe80::219:dbff:fee5:3f92%eth1]:5900
- host=`echo "$orig" | sed -e 's/\].*$//' -e 's/\[//'`
- disp=`echo "$orig" | sed -e 's/^.*\]://'`
- ipv6=1
-elif echo "$orig" | grep ':..*:' > /dev/null; then
- # ipv6 fe80::219:dbff:fee5:3f92%eth1:5900
- host=`echo "$orig" | sed -e 's/:[^:]*$//'`
- disp=`echo "$orig" | sed -e 's/^.*://'`
- ipv6=1
-else
- # regular host:port
- host=`echo "$orig" | awk -F: '{print $1}'`
- disp=`echo "$orig" | awk -F: '{print $2}'`
-fi
-
-if [ "X$reverse" != "X" -a "X$STUNNEL_LISTEN" = "X" -a "X$host" != "X" ]; then
- STUNNEL_LISTEN=$host
- echo "set STUNNEL_LISTEN=$STUNNEL_LISTEN"
-fi
-
-if [ "X$host" = "X" ]; then
- host=$localhost
-fi
-
-if [ "X$SSVNC_IPV6" = "X0" ]; then
- # disable checking for it.
- ipv6=0
-#elif [ "X$reverse" != "X" -a "X$ipv6" = "X1" ]; then
-# ipv6=0
-elif [ "X$ipv6" = "X1" ]; then
- :
-elif echo "$host" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then
- :
-else
- # regular hostname, can't be sure...
- gout=""
- if type getent > /dev/null 2>/dev/null; then
- gout=`getent hosts "$host" 2>/dev/null`
- fi
- if echo "$gout" | grep ':.*:' > /dev/null; then
- if echo "$gout" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then
- :
- else
- echo "ipv6: "`echo "$gout" | grep ':.*:' | head -n 1`
- ipv6=1
- fi
- fi
- if [ "X$ipv6" = "X0" ]; then
- hout=""
- if type host > /dev/null 2>/dev/null; then
- host "$host" >/dev/null 2>&1
- host "$host" >/dev/null 2>&1
- hout=`host "$host" 2>/dev/null`
- fi
- if echo "$hout" | grep -i 'has ipv6 address' > /dev/null; then
- if echo "$hout" | grep -i 'has address' > /dev/null; then
- :
- else
- echo "ipv6: "`echo "$hout" | grep -i 'has ipv6 address' | head -n 1`
- ipv6=1
- fi
- fi
- fi
- if [ "X$ipv6" = "X0" ]; then
- dout=""
- if type dig > /dev/null 2>/dev/null; then
- dout=`dig -t any "$host" 2>/dev/null`
- fi
- if echo "$dout" | grep -i "^$host" | grep '[ ]AAAA[ ]' > /dev/null; then
- if echo "$dout" | grep -i "^$host" | grep '[ ]A[ ]' > /dev/null; then
- :
- else
- echo "ipv6: "`echo "$dout" | grep -i '[ ]AAAA[ ]' | head -n 1`
- ipv6=1
- fi
- fi
- fi
- if [ "X$ipv6" = "X0" ]; then
- sout=`env LOOKUP="$host" \
- perl -e ' eval {use Socket}; exit 0 if $@;
- eval {use Socket6}; exit 0 if $@;
- @res = getaddrinfo($ENV{LOOKUP}, "daytime", AF_UNSPEC, SOCK_STREAM);
- $ipv4 = 0;
- $ipv6 = 0;
- $ip6 = "";
- while (scalar(@res) >= 5) {
- ($family, $socktype, $proto, $saddr, $canon, @res) = @res;
- $ipv4 = 1 if $family == AF_INET;
- $ipv6 = 1 if $family == AF_INET6;
- if ($family == AF_INET6 && $ip6 eq "") {
- my ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
- $ip6 = $host;
- }
- }
- if (! $ipv4 && $ipv6) {
- print "AF_INET6_ONLY: $ENV{LOOKUP}: $ip6\n";
- }
- exit 0;
- ' 2>/dev/null`
- if echo "$sout" | grep AF_INET6_ONLY > /dev/null; then
- echo "$sout"
- ipv6=1
- fi
- fi
-fi
-if [ "X$ipv6" = "X1" ]; then
- echo "ipv6: addr=$host disp=$disp"
-fi
-if [ "X$disp" = "X" ]; then
- port="" # probably -listen mode.
-elif [ $disp -lt 0 ]; then
- # negative means use |n| without question:
- port=`expr 0 - $disp`
-elif [ $disp -lt 200 ]; then
- # less than 200 means 5900+n
- if [ "X$reverse" = "X" ]; then
- port=`expr $disp + 5900`
- else
- port=`expr $disp + 5500`
- fi
-else
- # otherwise use the number directly, e.g. 443, 2345
- port=$disp
-fi
-
-if [ "X$ipv6" = "X1" -a "X$direct_connect" = "X1" ]; then
- if [ "X$proxy" = "X" -a "X$reverse" = "X" ]; then
- if [ "X$SSVNC_ULTRA_DSM" != "X" -a "X$have_uvnc_dsm_helper_ipv6" = "X1" ]; then
- :
- elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then
- :
- elif [ "X$SSVNC_NO_IPV6_PROXY_DIRECT" != "X" ]; then
- :
- elif [ "X$SSVNC_USE_OURS" = "X1" ]; then
- # requires 1.0.27 and later ssvncviewer binary
- :
- else
- proxy="ipv6://$host:$port"
- echo "direct connect: set proxy=$proxy"
- fi
- fi
-fi
-
-# (possibly) tell the vncviewer to only listen on lo:
-if [ "X$reverse" != "X" ]; then
- if [ "X$direct_connect" = "X" -o "X$proxy" != "X" -o "X$STUNNEL_LISTEN" != "X" ]; then
- VNCVIEWER_LISTEN_LOCALHOST=1
- export VNCVIEWER_LISTEN_LOCALHOST
- fi
-fi
-
-# try to find an open listening port via netstat(1):
-inuse=""
-if uname | grep Linux > /dev/null; then
- inuse=`netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'`
-elif uname | grep SunOS > /dev/null; then
- inuse=`netstat -an -f inet -P tcp | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $1}' | sed 's/^.*\.//'`
-elif uname | egrep -i 'bsd|darwin' > /dev/null; then
- inuse=`netstat -ant -f inet | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*\.//'`
-# add others...
-fi
-
-# this is a crude attempt for unique ports tags, etc.
-date_sec=`date +%S`
-
-# these are special cases of no vnc, e.g. sleep or xmessage.
-# these are for using ssvnc as a general port redirector.
-if echo "$VNCVIEWERCMD" | grep '^sleep[ ][ ]*[0-9][0-9]*' > /dev/null; then
- if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
- p=`echo "$VNCVIEWERCMD" | awk '{print $3}'`
- if [ "X$p" != "X" ]; then
- SS_VNCVIEWER_LISTEN_PORT=$p
- fi
- fi
- p2=`echo "$VNCVIEWERCMD" | awk '{print $2}'`
- VNCVIEWERCMD="eval sleep $p2; echo Local "
-elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; then
- if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
- p=`echo "$VNCVIEWERCMD" | awk '{print $2}'`
- SS_VNCVIEWER_LISTEN_PORT=$p
- fi
-fi
-
-# utility to find a free port to listen on.
-findfree() {
- try0=$1
- try=$try0
- use0=""
-
- if [ "X$SS_VNCVIEWER_LISTEN_PORT" != "X" ]; then
- echo "$SS_VNCVIEWER_LISTEN_PORT"
- return
- fi
- if [ $try -ge 6000 ]; then
- fmax=`expr $try + 1000`
- else
- fmax=6000
- fi
-
- while [ $try -lt $fmax ]
- do
- if [ "X$inuse" = "X" ]; then
- break
- fi
- if echo "$inuse" | grep -w $try > /dev/null; then
- :
- else
- use0=$try
- break
- fi
- try=`expr $try + 1`
- done
- if [ "X$use0" = "X" ]; then
- use0=`expr $date_sec + $try0`
- fi
-
- echo $use0
-}
-
-# utility for exiting; kills some helper processes,
-# removes files, etc.
-final() {
- echo ""
- if [ "X$tmp_cfg" != "X" ]; then
- rm -f $tmp_cfg
- fi
- if [ "X$SS_VNCVIEWER_RM" != "X" ]; then
- rm -f $SS_VNCVIEWER_RM 2>/dev/null
- fi
- if [ "X$tcert" != "X" ]; then
- rm -f $tcert
- fi
- if [ "X$pssh" != "X" ]; then
- echo "Terminating background ssh process"
- echo kill -TERM "$pssh"
- kill -TERM "$pssh" 2>/dev/null
- sleep 1
- kill -KILL "$pssh" 2>/dev/null
- pssh=""
- fi
- if [ "X$stunnel_pid" != "X" ]; then
- echo "Terminating background stunnel process"
- echo kill -TERM "$stunnel_pid"
- kill -TERM "$stunnel_pid" 2>/dev/null
- sleep 1
- kill -KILL "$stunnel_pid" 2>/dev/null
- stunnel_pid=""
- fi
- if [ "X$dsm_pid" != "X" ]; then
- echo "Terminating background ultravnc_dsm_helper process"
- echo kill -TERM "$dsm_pid"
- kill -TERM "$dsm_pid" 2>/dev/null
- sleep 1
- kill -KILL "$dsm_pid" 2>/dev/null
- stunnel_pid=""
- fi
- if [ "X$tail_pid" != "X" ]; then
- kill -TERM $tail_pid
- fi
- if [ "X$tail_pid2" != "X" ]; then
- kill -TERM $tail_pid2
- fi
-}
-
-if [ "X$reverse" = "X" ]; then
- # normal connections try 5930-5999:
- if [ "X$showcert" = "X" ]; then
- use=`findfree 5930`
- else
- # move away from normal place for (possibly many) -showcert
- pstart=`date +%S`
- pstart=`expr 6130 + $pstart + $pstart`
- use=`findfree $pstart`
- fi
- if [ $use -ge 5900 ]; then
- N=`expr $use - 5900`
- else
- N=$use
- fi
-else
- # reverse connections:
- p2=`expr $port + 30`
- use=`findfree $p2`
- if [ $use -ge 5500 ]; then
- N=`expr $use - 5500`
- else
- N=$use
- fi
-fi
-
-# this is for my special use of ss_vncip -> vncip viewer.
-if echo "$0" | grep vncip > /dev/null; then
- VNCVIEWERCMD="$VNCIPCMD"
-fi
-
-if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
- :
-elif [ "X$VNCVIEWERCMD_EXTRA_OPTS" != "X" ]; then
- VNCVIEWERCMD="$VNCVIEWERCMD $VNCVIEWERCMD_EXTRA_OPTS"
-fi
-
-# trick for the undocumented rsh://host:port method.
-rsh_setup() {
- if echo "$ssh_host" | grep '@' > /dev/null; then
- ul=`echo "$ssh_host" | awk -F@ '{print $1}'`
- ul="-l $ul"
- ssh_host=`echo "$ssh_host" | awk -F@ '{print $2}'`
- else
- ul=""
- fi
- ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'`
-}
-
-# trick for the undocumented rsh://host:port method.
-rsh_viewer() {
- trap "final" 0 2 15
- if [ "X$PORT" = "X" ]; then
- exit 1
- elif [ $PORT -ge 5900 ]; then
- vdpy=`expr $PORT - 5900`
- else
- vdpy=":$PORT"
- fi
- stty sane
- echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy
- echo ""
- $VNCVIEWERCMD "$@" $ssh_host:$vdpy
- if [ $? != 0 ]; then
- sleep 2
- $VNCVIEWERCMD "$@" $ssh_host:$vdpy
- fi
-}
-
-check_perl() {
- if type "$1" > /dev/null 2>&1; then
- :
- elif [ ! -x "$1" ]; then
- echo ""
- echo "*******************************************************"
- echo "** Problem finding the Perl command '$1': **"
- echo ""
- type "perl"
- echo ""
- echo "** Perhaps you need to install the Perl package. **"
- echo "*******************************************************"
- echo ""
- sleep 5
- fi
-}
-
-# this is the PPROXY tool. used only here for now...
-pcode() {
- tf=$1
- PPROXY_PROXY=$proxy; export PPROXY_PROXY
- PPROXY_DEST="$host:$port"; export PPROXY_DEST
- check_perl /usr/bin/perl
-
- cod='#!/usr/bin/perl
-
-# A hack to glue stunnel to a Web or SOCKS proxy, UltraVNC repeater for
-# client connections.
-# Also acts as a VeNCrypt bridge (by redirecting to stunnel.)
-
-use IO::Socket::INET;
-
-my $have_inet6 = "";
-eval "use IO::Socket::INET6;";
-$have_inet6 = 1 if $@ eq "";
-
-#my $have_sock6 = "";
-#eval "use Socket; use Socket6;";
-#$have_sock6 = 1 if $@ eq "";
-
-if (exists $ENV{PPROXY_LOOP_THYSELF}) {
- # used for reverse vnc, run a repeating outer loop.
- print STDERR "PPROXY_LOOP: $ENV{PPROXY_LOOP_THYSELF}\n";
- my $rm = $ENV{PPROXY_REMOVE};
- my $lp = $ENV{PPROXY_LOOP_THYSELF};
- delete $ENV{PPROXY_REMOVE};
- delete $ENV{PPROXY_LOOP_THYSELF};
- $ENV{PPROXY_LOOP_THYSELF_MASTER} = $$;
- my $pid = $$;
- my $dbg = 0;
- my $c = 0;
- use POSIX ":sys_wait_h";
- while (1) {
- $pid = fork();
- last if ! defined $pid;
- if ($pid eq "0") {
- last;
- }
- $c++;
- print STDERR "\nPPROXY_LOOP: pid=$$ child=$pid count=$c\n";
- while (1) {
- waitpid(-1, WNOHANG);
- fsleep(0.25);
- if (! kill 0, $pid) {
- print STDERR "PPROXY_LOOP: child=$pid gone.\n";
- last;
- }
- print STDERR "PPROXY_LOOP: child=$pid alive.\n" if $dbg;
- if (! -f $lp) {
- print STDERR "PPROXY_LOOP: flag file $lp gone, killing $pid\n";
- kill TERM, $pid;
- fsleep(0.1);
- wait;
- last;
- }
- print STDERR "PPROXY_LOOP: file exists $lp\n" if $dbg;
- }
- last if ! -f $lp;
- fsleep(0.25);
- }
- if ($pid ne "0") {
- unlink($0) if $rm;
- exit 0;
- }
-}
-
-if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) {
- print STDERR "PPROXY_PID: $$\n";
- sleep $ENV{PPROXY_SLEEP};
-}
-
-foreach my $var (qw(
- PPROXY_DEST
- PPROXY_KILLPID
- PPROXY_LISTEN
- PPROXY_PROXY
- PPROXY_REMOVE
- PPROXY_REPEATER
- PPROXY_REVERSE
- PPROXY_SLEEP
- PPROXY_SOCKS
- PPROXY_VENCRYPT
- PPROXY_VENCRYPT_VIEWER_BRIDGE
- )) {
- if (0 || $ENV{SS_DEBUG} || $ENV{SSVNC_VENCRYPT_DEBUG}) {
- print STDERR "$var: $ENV{$var}\n";
- }
-}
-
-if ($ENV{PPROXY_SOCKS} ne "" && $ENV{PPROXY_PROXY} !~ m,^socks5?://,i) {
- if ($ENV{PPROXY_SOCKS} eq "5") {
- $ENV{PPROXY_PROXY} = "socks5://$ENV{PPROXY_PROXY}";
- } else {
- $ENV{PPROXY_PROXY} = "socks://$ENV{PPROXY_PROXY}";
- }
-}
-
-my $rfbSecTypeAnonTls = 18;
-my $rfbSecTypeVencrypt = 19;
-
-my $rfbVencryptPlain = 256;
-my $rfbVencryptTlsNone = 257;
-my $rfbVencryptTlsVnc = 258;
-my $rfbVencryptTlsPlain = 259;
-my $rfbVencryptX509None = 260;
-my $rfbVencryptX509Vnc = 261;
-my $rfbVencryptX509Plain = 262;
-
-my $handshake_file = "";
-if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) {
- $handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE};
-}
-
-my $have_gettimeofday = 0;
-eval "use Time::HiRes;";
-if ($@ eq "") {
- $have_gettimeofday = 1;
-}
-sub gettime {
- my $t = "0.0";
- if ($have_gettimeofday) {
- $t = Time::HiRes::gettimeofday();
- }
- return $t;
-}
-
-my $listen_handle = "";
-my $sock = "";
-my $parent = $$;
-
-my $initial_data = "";
-
-if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) {
- my ($from, $to) = split(/,/, $ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE});
- do_vencrypt_viewer_bridge($from, $to);
- exit 0;
-}
-
-my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3);
-my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", "");
-
-($first, $mode_1st) = url_parse($first);
-
-my ($proxy_host, $proxy_port) = ($first, "");
-if ($proxy_host =~ /^(.*):(\d+)$/) {
- $proxy_host = $1;
- $proxy_port = $2;
-}
-my $connect = $ENV{PPROXY_DEST};
-
-if ($second ne "") {
- ($second, $mode_2nd) = url_parse($second);
-}
-
-if ($third ne "") {
- ($third, $mode_3rd) = url_parse($third);
-}
-
-
-print STDERR "\n";
-print STDERR "PPROXY v0.4: a tool for Web, SOCKS, and UltraVNC proxies and for\n";
-print STDERR "PPROXY v0.4: IPv6 and VNC VeNCrypt bridging.\n";
-print STDERR "proxy_host: $proxy_host\n";
-print STDERR "proxy_port: $proxy_port\n";
-print STDERR "proxy_connect: $connect\n";
-print STDERR "pproxy_params: $ENV{PPROXY_PROXY}\n";
-print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n";
-print STDERR "pproxy_reverse: $ENV{PPROXY_REVERSE}\n";
-print STDERR "io_socket_inet6: $have_inet6\n";
-print STDERR "\n";
-if (! $have_inet6) {
- print STDERR "PPROXY: To enable IPv6 connections, install the IO::Socket::INET6 perl module.\n\n";
-}
-
-if (1) {
- print STDERR "pproxy 1st: $first\t- $mode_1st\n";
- print STDERR "pproxy 2nd: $second\t- $mode_2nd\n";
- print STDERR "pproxy 3rd: $third\t- $mode_3rd\n";
- print STDERR "\n";
-}
-
-sub pdie {
- my $msg = shift;
- kill_proxy_pids();
- die "$msg";
-}
-
-if ($ENV{PPROXY_REVERSE} ne "") {
- my ($rhost, $rport) = ($ENV{PPROXY_REVERSE}, "");
- if ($rhost =~ /^(.*):(\d+)$/) {
- $rhost = $1;
- $rport = $2;
- }
- $rport = 5900 unless $rport;
- my $emsg = "";
- $listen_handle = IO::Socket::INET->new(
- PeerAddr => $rhost,
- PeerPort => $rport,
- Proto => "tcp"
- );
- $emsg = $!;
- if (! $listen_handle && $have_inet6) {
- eval {$listen_handle = IO::Socket::INET6->new(
- PeerAddr => $rhost,
- PeerPort => $rport,
- Proto => "tcp"
- );};
- $emsg .= " / $!";
- }
- if (! $listen_handle) {
- pdie "pproxy: $emsg -- PPROXY_REVERSE\n";
- }
- print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n";
-
-} elsif ($ENV{PPROXY_LISTEN} ne "") {
- my $listen_sock = "";
- my $maxtry = 12;
- my $sleep = 5;
- my $p2 = "";
- my $emsg = "";
- for (my $i=0; $i < $maxtry; $i++) {
- my ($if, $p) = ("", $ENV{PPROXY_LISTEN});
- if ($p =~ /^(.*):(\d+)$/) {
- $if = $1;
- $p = $2;
- }
- $p2 = "*:$p";
- if ($if eq "") {
- $if = "localhost";
- }
- print STDERR "pproxy interface: $if\n";
-
- $emsg = "";
- if (($if eq "INADDR_ANY6" || $if eq "::") && $have_inet6) {
- eval {$listen_sock = IO::Socket::INET6->new(
- Listen => 2,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::",
- LocalPort => $p,
- Proto => "tcp"
- );};
- $p2 = ":::$p";
- } elsif ($if =~ /^INADDR_ANY/) {
- $listen_sock = IO::Socket::INET->new(
- Listen => 2,
- ReuseAddr => 1,
- LocalPort => $p,
- Proto => "tcp"
- );
- } elsif (($if eq "INADDR_LOOPBACK6" || $if eq "::1") && $have_inet6) {
- $p2 = "::1:$p";
- eval {$listen_sock = IO::Socket::INET6->new(
- Listen => 2,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => "::1",
- LocalPort => $p,
- Proto => "tcp"
- );};
- $p2 = "::1:$p";
- } else {
- $p2 = "$if:$p";
- $listen_sock = IO::Socket::INET->new(
- Listen => 2,
- ReuseAddr => 1,
- LocalAddr => $if,
- LocalPort => $p,
- Proto => "tcp"
- );
- $emsg = $!;
-
- if (! $listen_sock && $have_inet6) {
- print STDERR "PPROXY_LISTEN: retry with INET6\n";
- eval {$listen_sock = IO::Socket::INET6->new(
- Listen => 2,
- ReuseAddr => 1,
- Domain => AF_INET6,
- LocalAddr => $if,
- LocalPort => $p,
- Proto => "tcp"
- );};
- $emsg .= " / $!";
- }
- }
- if (! $listen_sock) {
- if ($i < $maxtry - 1) {
- warn "pproxy: $emsg $!\n";
- warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n";
- sleep $sleep;
- }
- } else {
- last;
- }
- }
- if (! $listen_sock) {
- pdie "pproxy: $emsg -- PPROXY_LISTEN\n";
- }
- print STDERR "pproxy: listening on $p2\n";
- my $ip;
- ($listen_handle, $ip) = $listen_sock->accept();
- my $err = $!;
- close $listen_sock;
- if (! $listen_handle) {
- pdie "pproxy: $err\n";
- }
-
- if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) {
- my $sml = $ENV{SSVNC_MULTIPLE_LISTEN};
- if ($sml ne "" && $sml ne "0") {
- setpgrp(0, 0);
- if (fork()) {
- close $viewer_sock;
- wait;
- exit 0;
- }
- if (fork()) {
- close $viewer_sock;
- exit 0;
- }
- setpgrp(0, 0);
- $parent = $$;
- }
- }
-}
-
-$sock = IO::Socket::INET->new(
- PeerAddr => $proxy_host,
- PeerPort => $proxy_port,
- Proto => "tcp"
-);
-
-my $err = "";
-
-if (! $sock && $have_inet6) {
- $err = $!;
-
- print STDERR "pproxy: $!\n";
-
- eval {$sock = IO::Socket::INET6->new(
- PeerAddr => $proxy_host,
- PeerPort => $proxy_port,
- Proto => "tcp"
- );};
- $err .= " / $!";
-}
-
-if (! $sock && ($proxy_host =~ /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i || $proxy_host =~ /^::ffff:([\da-f]+:[\da-f]+)$/i)) {
- print STDERR "pproxy: $!\n";
- my $ipv4_addr = $1;
- if ($ipv4_addr =~ /:/) {
- my ($a, $b) = split(/:/, $ipv4_addr);
- $a = hex($a);
- $b = hex($b);
- $ipv4_addr = sprintf("%d.", ($a & 0xff00) >> 8);
- $ipv4_addr .= sprintf("%d.", ($a & 0x00ff));
- $ipv4_addr .= sprintf("%d.", ($b & 0xff00) >> 8);
- $ipv4_addr .= sprintf("%d", ($b & 0x00ff));
- }
-
- print STDERR "pproxy: re-trying with ipv4 addr: $ipv4_addr\n";
-
- eval {$sock = IO::Socket::INET->new(
- PeerAddr => $ipv4_addr,
- PeerPort => $proxy_port,
- Proto => "tcp"
- );};
- $err .= " / $!";
-}
-
-if (! $sock) {
- unlink($0) if $ENV{PPROXY_REMOVE};
- pdie "pproxy: $err\n";
-}
-
-unlink($0) if $ENV{PPROXY_REMOVE};
-
-if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_VENCRYPT_REVERSE}) {
- print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n";
- my $tmp_swap = $sock;
- $sock = $listen_handle;
- $listen_handle = $tmp_swap;
-}
-
-$cur_proxy = $first;
-setmode($mode_1st);
-
-if ($second ne "") {
- connection($second, 1);
-
- setmode($mode_2nd);
- $cur_proxy = $second;
-
- if ($third ne "") {
- connection($third, 2);
- setmode($mode_3rd);
- $cur_proxy = $third;
- connection($connect, 3);
- } else {
- connection($connect, 2);
- }
-} else {
- connection($connect, 1);
-}
-
-sub kill_proxy_pids() {
- if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) {
- return;
- }
- if ($ENV{PPROXY_KILLPID}) {
- foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) {
- if ($p =~ /^(\+|-)/) {
- $p = $parent + $p;
- }
- print STDERR "kill TERM, $p (PPROXY_KILLPID)\n";
- kill "TERM", $p;
- }
- }
-}
-
-sub xfer {
- my($in, $out) = @_;
- $RIN = $WIN = $EIN = "";
- $ROUT = "";
- vec($RIN, fileno($in), 1) = 1;
- vec($WIN, fileno($in), 1) = 1;
- $EIN = $RIN | $WIN;
-
- while (1) {
- my $nf = 0;
- while (! $nf) {
- $nf = select($ROUT=$RIN, undef, undef, undef);
- }
- my $len = sysread($in, $buf, 8192);
- if (! defined($len)) {
- next if $! =~ /^Interrupted/;
- print STDERR "pproxy[$$]: $!\n";
- last;
- } elsif ($len == 0) {
- print STDERR "pproxy[$$]: Input is EOF.\n";
- last;
- }
- my $offset = 0;
- my $quit = 0;
- while ($len) {
- my $written = syswrite($out, $buf, $len, $offset);
- if (! defined $written) {
- print STDERR "pproxy[$$]: Output is EOF. $!\n";
- $quit = 1;
- last;
- }
- $len -= $written;
- $offset += $written;
- }
- last if $quit;
- }
- close($out);
- close($in);
- print STDERR "pproxy[$$]: finished xfer.\n";
-}
-
-sub handler {
- print STDERR "pproxy[$$]: got SIGTERM.\n";
- close $listen_handle if $listen_handle;
- close $sock if $sock;
- exit;
-}
-
-sub xfer_both {
- $child = fork;
-
- if (! defined $child) {
- kill_proxy_pids();
- exit 1;
- }
-
- $SIG{TERM} = "handler";
-
- if ($child) {
- if ($listen_handle) {
- print STDERR "pproxy parent[$$] listen_handle -> socket\n";
- xfer($listen_handle, $sock);
- } else {
- print STDERR "pproxy parent[$$] STDIN -> socket\n";
- xfer(STDIN, $sock);
- }
- select(undef, undef, undef, 0.25);
- if (kill 0, $child) {
- select(undef, undef, undef, 0.9);
- if (kill 0, $child) {
- print STDERR "pproxy[$$]: kill TERM child $child\n";
- kill "TERM", $child;
- } else {
- print STDERR "pproxy[$$]: child $child gone.\n";
- }
- }
- } else {
- select(undef, undef, undef, 0.05);
- if ($listen_handle) {
- print STDERR "pproxy child [$$] socket -> listen_handle\n";
- if ($initial_data ne "") {
- my $len = length $initial_data;
- print STDERR "pproxy child [$$] sending initial_data, length $len\n\n";
- syswrite($listen_handle, $initial_data, $len);
- } else {
- print STDERR "\n";
- }
- xfer($sock, $listen_handle);
- } else {
- print STDERR "pproxy child [$$] socket -> STDOUT\n";
- if ($initial_data ne "") {
- my $len = length $initial_data;
- print STDERR "pproxy child [$$] sending initial_data, length $len\n\n";
- syswrite(STDOUT, $initial_data, $len);
- } else {
- print STDERR "\n";
- }
- xfer($sock, STDOUT);
- }
- select(undef, undef, undef, 0.25);
- if (kill 0, $parent) {
- select(undef, undef, undef, 0.8);
- if (kill 0, $parent) {
- print STDERR "pproxy[$$]: kill TERM parent $parent\n";
- kill "TERM", $parent;
- } else {
- print STDERR "pproxy[$$]: parent $parent gone.\n";
- }
- }
- }
-
- kill_proxy_pids();
-}
-
-xfer_both();
-
-exit;
-
-sub fsleep {
- select(undef, undef, undef, shift);
-}
-
-sub url_parse {
- my $hostport = shift;
- my $mode = "http";
- if ($hostport =~ m,^socks4?://(\S*)$,i) {
- $mode = "socks4";
- $hostport = $1;
- } elsif ($hostport =~ m,^socks5://(\S*)$,i) {
- $mode = "socks5";
- $hostport = $1;
- } elsif ($hostport =~ m,^https?://(\S*)$,i) {
- $mode = "http";
- $hostport = $1;
- } elsif ($hostport =~ m,^ipv6://(\S*)$,i) {
- $mode = "ipv6";
- $hostport = $1;
- } elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) {
- # ultravnc repeater proxy.
- $hostport = $1;
- $mode = "repeater:$2";
- if ($hostport !~ /:\d+$/) {
- $hostport .= ":5900";
- }
- } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) {
- # vencrypt handshake.
- $hostport = $1;
- my $m = "connect";
- if ($hostpost =~ /^(\S+)\+(\S+)$/) {
- $hostport = $1;
- $mode = $2;
- }
- $mode = "vencrypt:$m";
- if ($hostport !~ /:\d+$/) {
- $hostport .= ":5900";
- }
- }
- return ($hostport, $mode);
-}
-
-sub setmode {
- my $mode = shift;
- $ENV{PPROXY_REPEATER} = "";
- $ENV{PPROXY_VENCRYPT} = "";
- if ($mode =~ /^socks/) {
- if ($mode =~ /^socks5/) {
- $ENV{PPROXY_SOCKS} = 5;
- } else {
- $ENV{PPROXY_SOCKS} = 1;
- }
- } elsif ($mode =~ /^ipv6/i) {
- $ENV{PPROXY_SOCKS} = 0;
- } elsif ($mode =~ /^repeater:(.*)/) {
- $ENV{PPROXY_REPEATER} = $1;
- $ENV{PPROXY_SOCKS} = "";
- } elsif ($mode =~ /^vencrypt:(.*)/) {
- $ENV{PPROXY_VENCRYPT} = $1;
- $ENV{PPROXY_SOCKS} = "";
- } else {
- $ENV{PPROXY_SOCKS} = "";
- }
-}
-
-sub connection {
- my ($CONNECT, $w) = @_;
-
- my $con = "";
- my $msg = "";
-
- if ($ENV{PPROXY_SOCKS} eq "5") {
- # SOCKS5
- my ($h, $p) = ($CONNECT, "");
- if ($h =~ /^(.*):(\d+)$/) {
- $h = $1;
- $p = $2;
- }
- $con .= pack("C", 0x05);
- $con .= pack("C", 0x01);
- $con .= pack("C", 0x00);
-
- $msg = "SOCKS5 via $cur_proxy to $h:$p\n\n";
- print STDERR "proxy_request$w: $msg";
-
- syswrite($sock, $con, length($con));
-
- my ($n1, $n2, $n3, $n4, $n5, $n6);
- my ($r1, $r2, $r3, $r4, $r5, $r6);
- my ($s1, $s2, $s3, $s4, $s5, $s6);
-
- $n1 = sysread($sock, $r1, 1);
- $n2 = sysread($sock, $r2, 1);
-
- $s1 = unpack("C", $r1);
- $s2 = unpack("C", $r2);
- if ($s1 != 0x05 || $s2 != 0x00) {
- print STDERR "SOCKS5 fail s1=$s1 s2=$s2 n1=$n1 n2=$n2\n";
- close $sock;
- exit(1);
- }
-
- $con = "";
- $con .= pack("C", 0x05);
- $con .= pack("C", 0x01);
- $con .= pack("C", 0x00);
- $con .= pack("C", 0x03);
- $con .= pack("C", length($h));
- $con .= $h;
- $con .= pack("C", $p >> 8);
- $con .= pack("C", $p & 0xff);
-
- syswrite($sock, $con, length($con));
-
- $n1 = sysread($sock, $r1, 1);
- $n2 = sysread($sock, $r2, 1);
- $n3 = sysread($sock, $r3, 1);
- $n4 = sysread($sock, $r4, 1);
- $s1 = unpack("C", $r1);
- $s2 = unpack("C", $r2);
- $s3 = unpack("C", $r3);
- $s4 = unpack("C", $r4);
-
- if ($s4 == 0x1) {
- sysread($sock, $r5, 4 + 2);
- } elsif ($s4 == 0x3) {
- sysread($sock, $r5, 1);
- $s5 = unpack("C", $r5);
- sysread($sock, $r6, $s5 + 2);
- } elsif ($s4 == 0x4) {
- sysread($sock, $r5, 16 + 2);
- }
-
- if ($s1 != 0x5 || $s2 != 0x0 || $s3 != 0x0) {
- print STDERR "SOCKS5 failed: s1=$s1 s2=$s2 s3=$s3 s4=$s4 n1=$n1 n2=$n2 n3=$n3 n4=$n4\n";
- close $sock;
- exit(1);
- }
-
- } elsif ($ENV{PPROXY_SOCKS} eq "1") {
- # SOCKS4 SOCKS4a
- my ($h, $p) = ($CONNECT, "");
- if ($h =~ /^(.*):(\d+)$/) {
- $h = $1;
- $p = $2;
- }
- $con .= pack("C", 0x04);
- $con .= pack("C", 0x01);
- $con .= pack("n", $p);
-
- my $SOCKS_4a = 0;
- if ($h eq "localhost" || $h eq "127.0.0.1") {
- $con .= pack("C", 127);
- $con .= pack("C", 0);
- $con .= pack("C", 0);
- $con .= pack("C", 1);
- } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
- $con .= pack("C", $1);
- $con .= pack("C", $2);
- $con .= pack("C", $3);
- $con .= pack("C", $4);
- } else {
- $con .= pack("C", 0);
- $con .= pack("C", 0);
- $con .= pack("C", 0);
- $con .= pack("C", 3);
- $SOCKS_4a = 1;
- }
-
- $con .= "nobody";
- $con .= pack("C", 0);
-
- $msg = "SOCKS4 via $cur_proxy to $h:$p\n\n";
- if ($SOCKS_4a) {
- $con .= $h;
- $con .= pack("C", 0);
- $msg =~ s/SOCKS4/SOCKS4a/;
- }
- print STDERR "proxy_request$w: $msg";
- syswrite($sock, $con, length($con));
-
- my $ok = 1;
- for (my $i = 0; $i < 8; $i++) {
- my $c;
- sysread($sock, $c, 1);
- my $s = unpack("C", $c);
- if ($i == 0) {
- $ok = 0 if $s != 0x0;
- } elsif ($i == 1) {
- $ok = 0 if $s != 0x5a;
- }
- }
- if (! $ok) {
- print STDERR "SOCKS4 failed.\n";
- close $sock;
- exit(1);
- }
- } elsif ($ENV{PPROXY_SOCKS} eq "0") {
- # hack for ipv6 "proxy", nothing to do, assume INET6 call worked.
- ;
- } elsif ($ENV{PPROXY_REPEATER} ne "") {
- my $rep = $ENV{PPROXY_REPEATER};
- print STDERR "repeater: $rep\n";
- $rep .= pack("x") x 250;
- syswrite($sock, $rep, 250);
-
- my $rfb = "";
-
- my $ok = 1;
- for (my $i = 0; $i < 12; $i++) {
- my $c;
- last if $ENV{PPROXY_GENERIC_REPEATER};
- sysread($sock, $c, 1);
- print STDERR $c;
- $rfb .= $c;
- }
- if ($rfb ne "" && $rfb !~ /^RFB 000\.000/) {
- $initial_data = $rfb;
- $rfb =~ s/\n//g;
- print STDERR "detected non-UltraVNC repeater; forwarding \"$rfb\"\nlength: ", length($initial_data), "\n";
- }
- } elsif ($ENV{PPROXY_VENCRYPT} ne "") {
- my $vencrypt = $ENV{PPROXY_VENCRYPT};
- vencrypt_dialog($vencrypt);
-
- } else {
- # Web Proxy:
- $con = "CONNECT $CONNECT HTTP/1.1\r\n";
- $con .= "Host: $CONNECT\r\n";
- $con .= "Connection: close\r\n\r\n";
- $msg = $con;
-
- print STDERR "proxy_request$w: via $cur_proxy:\n$msg";
- syswrite($sock, $con, length($con));
-
- my $rep = "";
- my $n = 0;
- while ($rep !~ /\r\n\r\n/ && $n < 30000) {
- my $c;
- sysread($sock, $c, 1);
- print STDERR $c;
- $rep .= $c;
- $n++;
- }
- if ($rep !~ m,HTTP/.* 200,) {
- print STDERR "HTTP CONNECT failed.\n";
- close $sock;
- exit(1);
- }
- }
-}
-
-sub vdie {
- append_handshake("done\n");
- close $sock;
- kill_proxy_pids();
- exit(1);
-}
-
-sub anontls_handshake {
- my ($vmode, $db) = @_;
-
- print STDERR "\nPPROXY: Doing ANONTLS Handshake\n";
-
- my $psec = pack("C", $rfbSecTypeAnonTls);
- syswrite($sock, $psec, 1);
-
- append_handshake("done\n");
-}
-
-sub vencrypt_handshake {
-
- my ($vmode, $db) = @_;
-
- print STDERR "\nPPROXY: Doing VeNCrypt Handshake\n";
-
- my $psec = pack("C", $rfbSecTypeVencrypt);
-
- if (exists $ENV{SSVNC_TEST_SEC_TYPE}) {
- my $fake = $ENV{SSVNC_TEST_SEC_TYPE};
- print STDERR "PPROXY: sending sec-type: $fake\n";
- $psec = pack("C", $fake);
- }
-
- syswrite($sock, $psec, 1);
-
- my $vmajor;
- my $vminor;
- sysread($sock, $vmajor, 1);
- sysread($sock, $vminor, 1);
-
- vdie if $vmajor eq "" || $vminor eq "";
-
- $vmajor = unpack("C", $vmajor);
- $vminor = unpack("C", $vminor);
- print STDERR "server vencrypt version $vmajor.$vminor\n" if $db;
-
- if (exists $ENV{SSVNC_TEST_SEC_TYPE}) {
- print STDERR "PPROXY: continuing on in test mode.\n";
- } else {
- vdie if $vmajor ne 0;
- vdie if $vminor < 2;
- }
-
- $vmajor = pack("C", 0);
- $vminor = pack("C", 2);
- append_handshake("subversion=0.2\n");
-
- syswrite($sock, $vmajor, 1);
- syswrite($sock, $vminor, 1);
-
- my $result;
- sysread($sock, $result, 1);
- print STDERR "result empty\n" if $db && $result eq "";
-
- vdie if $result eq "";
- $result = unpack("C", $result);
- print STDERR "result=$result\n" if $db;
-
- vdie if $result ne 0;
-
- my $nsubtypes;
- sysread($sock, $nsubtypes, 1);
-
- vdie if $nsubtypes eq "";
- $nsubtypes = unpack("C", $nsubtypes);
- print STDERR "nsubtypes=$nsubtypes\n" if $db;
-
- my %subtypes;
-
- for (my $i = 0; $i < $nsubtypes; $i++) {
- my $subtype = "";
- sysread($sock, $subtype, 4);
- vdie if length($subtype) != 4;
-
- # XXX fix 64bit.
- $subtype = unpack("N", $subtype);
- print STDERR "subtype: $subtype\n" if $db;
- $subtypes{$subtype} = 1;
- append_handshake("sst$i=$subtype\n");
- }
-
- my $subtype = 0;
- if (exists $subtypes{$rfbVencryptX509None}) {
- $subtype = $rfbVencryptX509None;
- print STDERR "selected rfbVencryptX509None\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptX509Vnc}) {
- $subtype = $rfbVencryptX509Vnc;
- print STDERR "selected rfbVencryptX509Vnc\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptX509Plain}) {
- $subtype = $rfbVencryptX509Plain;
- print STDERR "selected rfbVencryptX509Plain\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptTlsNone}) {
- $subtype = $rfbVencryptTlsNone;
- print STDERR "selected rfbVencryptTlsNone\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptTlsVnc}) {
- $subtype = $rfbVencryptTlsVnc;
- print STDERR "selected rfbVencryptTlsVnc\n" if $db;
- } elsif (exists $subtypes{$rfbVencryptTlsPlain}) {
- $subtype = $rfbVencryptTlsPlain;
- print STDERR "selected rfbVencryptTlsPlain\n" if $db;
- }
-
- if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) {
- my $fake = $ENV{SSVNC_TEST_SEC_SUBTYPE};
- print STDERR "PPROXY: sending sec-subtype: $fake\n";
- $subtype = $fake;
- }
-
- append_handshake("subtype=$subtype\n");
-
- my $pst = pack("N", $subtype);
- syswrite($sock, $pst, 4);
-
- if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) {
- print STDERR "PPROXY: continuing on in test mode.\n";
- } else {
- vdie if $subtype == 0;
- }
-
- my $ok;
- sysread($sock, $ok, 1);
- $ok = unpack("C", $ok);
- print STDERR "ok=$ok\n" if $db;
-
- append_handshake("done\n");
-
- vdie if $ok == 0;
-}
-
-sub vencrypt_dialog {
- my $vmode = shift;
- my $db = 0;
-
- $db = 1 if exists $ENV{SS_DEBUG};
- $db = 1 if exists $ENV{SSVNC_VENCRYPT_DEBUG};
-
- append_handshake("mode=$vmode\n");
-
- my $server_rfb = "";
- #syswrite($sock, $rep, 250);
- for (my $i = 0; $i < 12; $i++) {
- my $c;
- sysread($sock, $c, 1);
- $server_rfb .= $c;
- print STDERR $c;
- }
- print STDERR "server_rfb: $server_rfb\n" if $db;
- append_handshake("server=$server_rfb");
-
- my $minor = "";
- if ($server_rfb =~ /^RFB 003\.(\d+)/) {
- $minor = $1;
- } else {
- vdie;
- }
- my $viewer_rfb = "RFB 003.008\n";
- if ($minor < 7) {
- vdie;
- } elsif ($minor == 7) {
- $viewer_rfb = "RFB 003.007\n";
- }
- my $nsec;
- my $t1 = gettime();
- my $t0 = gettime();
-
- syswrite($sock, $viewer_rfb, 12);
- sysread($sock, $nsec, 1);
-
- $t1 = gettime();
- $t1 = sprintf("%.6f", $t1 - $t0);
-
- append_handshake("viewer=$viewer_rfb");
- append_handshake("latency=$t1\n");
-
- vdie if $nsec eq "";
-
- $nsec = unpack("C", $nsec);
-
- print STDERR "nsec: $nsec\n" if $db;
- vdie if $nsec eq 0 || $nsec > 100;
-
- my %sectypes = ();
-
- for (my $i = 0; $i < $nsec; $i++) {
- my $sec;
- sysread($sock, $sec, 1);
- vdie if $sec eq "";
- $sec = unpack("C", $sec);
- print STDERR "sec: $sec\n" if $db;
- $sectypes{$sec} = 1;
- }
-
- if (exists $sectypes{$rfbSecTypeVencrypt}) {
- print STDERR "found rfbSecTypeVencrypt\n" if $db;
- append_handshake("sectype=$rfbSecTypeVencrypt\n");
- vencrypt_handshake($vmode, $db);
- } elsif (exists $sectypes{$rfbSecTypeAnonTls}) {
- print STDERR "found rfbSecTypeAnonTls\n" if $db;
- append_handshake("sectype=$rfbSecTypeAnonTls\n");
- anontls_handshake($vmode, $db);
- } else {
- print STDERR "No supported sec-type found\n" if $db;
- vdie;
- }
-}
-
-sub append_handshake {
- my $str = shift;
- if ($handshake_file) {
- if (open(HSF, ">>$handshake_file")) {
- print HSF $str;
- close HSF;
- }
- }
-}
-
-sub do_vencrypt_viewer_bridge {
- my ($listen, $connect) = @_;
- print STDERR "\npproxy: starting vencrypt_viewer_bridge[$$]: $listen \-> $connect\n";
- my $db = 0;
- my $backwards = 0;
- if ($listen < 0) {
- $backwards = 1;
- $listen = -$listen;
- }
- if ($handshake_file eq "") {
- die "pproxy: vencrypt_viewer_bridge[$$]: no SSVNC_PREDIGESTED_HANDSHAKE\n";
- }
- my $listen_sock;
- my $maxtry = 12;
- my $sleep = 5;
- for (my $i=0; $i < $maxtry; $i++) {
- $listen_sock = IO::Socket::INET->new(
- Listen => 2,
- ReuseAddr => 1,
- LocalAddr => "127.0.0.1",
- LocalPort => $listen,
- Proto => "tcp"
- );
- if (! $listen_sock) {
- if ($i < $maxtry - 1) {
- warn "pproxy: vencrypt_viewer_bridge[$$]: $!\n";
- warn "Could not listen on port $listen, retrying in $sleep seconds... (Ctrl-C to quit)\n";
- sleep $sleep;
- }
- } else {
- last;
- }
- }
- if (! $listen_sock) {
- die "pproxy: vencrypt_viewer_bridge[$$]: $!\n";
- }
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: listening on port $listen\n\n";
- my ($viewer_sock, $ip) = $listen_sock->accept();
- my $err = $!;
- close $listen_sock;
- if (! $viewer_sock) {
- die "pproxy: vencrypt_viewer_bridge[$$]: $err\n";
- }
- if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) {
- my $sml = $ENV{SSVNC_MULTIPLE_LISTEN};
- if ($sml ne "" && $sml ne "0") {
- setpgrp(0, 0);
- if (fork()) {
- close $viewer_sock;
- wait;
- exit 0;
- }
- if (fork()) {
- close $viewer_sock;
- exit 0;
- }
- setpgrp(0, 0);
- $parent = $$;
- }
- }
- print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db;
-
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n";
- my $server_sock = IO::Socket::INET->new(
- PeerAddr => "127.0.0.1",
- PeerPort => $connect,
- Proto => "tcp"
- );
- print STDERR "vencrypt_viewer_bridge[$$]: server_sock $server_sock\n" if $db;
- if (! $server_sock) {
- my $err = $!;
- die "pproxy: vencrypt_viewer_bridge[$$]: $err\n";
- }
-
- if ($backwards) {
- print STDERR "vencrypt_viewer_bridge[$$]: reversing roles of viewer and server.\n";
- my $t = $viewer_sock;
- $viewer_sock = $server_sock;
- $server_sock = $t;
- }
-
- my %hs = ();
- my $dt = 0.2;
- my $slept = 0.0;
- while ($slept < 20.0) {
- select(undef, undef, undef, $dt);
- $slept += $dt;
- if (-f $handshake_file && open(HSF, "<$handshake_file")) {
- my $done = 0;
- %hs = ();
- my $str = "";
- while (<HSF>) {
- print STDERR "vencrypt_viewer_bridge[$$]: $_" if $ENV{VENCRYPT_VIEWER_BRIDGE_DEBUG};
- $str .= "vencrypt_viewer_bridge[$$]: $_";
- chomp;
- if ($_ eq "done") {
- $done = 1;
- } else {
- my ($k, $v) = split(/=/, $_, 2);
- if ($k ne "" && $v ne "") {
- $hs{$k} = $v;
- }
- }
- }
- close HSF;
- if ($done) {
- print STDERR "\n" . $str;
- last;
- }
- }
- }
- if (! exists $hs{server}) {
- $hs{server} = "RFB 003.008";
- }
- if (! exists $hs{sectype}) {
- unlink($handshake_file);
- die "pproxy: vencrypt_viewer_bridge[$$]: no sectype.\n";
- }
- syswrite($viewer_sock, "$hs{server}\n", length($hs{server}) + 1);
- my $viewer_rfb = "";
- for (my $i = 0; $i < 12; $i++) {
- my $c;
- sysread($viewer_sock, $c, 1);
- $viewer_rfb .= $c;
- print STDERR $c;
- }
- my $viewer_major = 3;
- my $viewer_minor = 8;
- if ($viewer_rfb =~ /RFB (\d+)\.(\d+)/) {
- $viewer_major = $1;
- $viewer_minor = $2;
- }
- my $u0 = pack("C", 0);
- my $u1 = pack("C", 1);
- my $u2 = pack("C", 2);
- if ($hs{sectype} == $rfbSecTypeAnonTls) {
- unlink($handshake_file);
- print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeAnonTls\n";
- if ($viewer_major > 3 || $viewer_minor >= 7) {
- ; # setup ok, proceed to xfer.
- } else {
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n";
- my $n;
- sysread($server_sock, $n, 1);
- $n = unpack("C", $n);
- if ($n == 0) {
- die "pproxy: vencrypt_viewer_bridge[$$]: nsectypes == $n.\n";
- }
- my %types;
- for (my $i = 0; $i < $n; $i++) {
- my $t;
- sysread($server_sock, $t, 1);
- $t = unpack("C", $t);
- $types{$t} = 1;
- }
- my $use = 1; # None
- if (exists $types{1}) {
- $use = 1; # None
- } elsif (exists $types{2}) {
- $use = 2; # VncAuth
- } else {
- die "pproxy: vencrypt_viewer_bridge[$$]: no valid sectypes" . join(",", keys %types) . "\n";
- }
-
- # send 4 bytes sectype to viewer:
- # (note this should be MSB, network byte order...)
- my $up = pack("C", $use);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $up, 1);
- # and tell server the one we selected:
- syswrite($server_sock, $up, 1);
- if ($use == 1) {
- # even None has security result, so read it here and discard it.
- my $sr = "";
- sysread($server_sock, $sr, 4);
- }
- }
- } elsif ($hs{sectype} == $rfbSecTypeVencrypt) {
- print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeVencrypt\n";
- if (! exists $hs{subtype}) {
- unlink($handshake_file);
- die "pproxy: vencrypt_viewer_bridge[$$]: no subtype.\n";
- }
- my $fake_type = "None";
- my $plain = 0;
- my $sub_type = $hs{subtype};
- if ($sub_type == $rfbVencryptTlsNone) {
- $fake_type = "None";
- } elsif ($sub_type == $rfbVencryptTlsVnc) {
- $fake_type = "VncAuth";
- } elsif ($sub_type == $rfbVencryptTlsPlain) {
- $fake_type = "None";
- $plain = 1;
- } elsif ($sub_type == $rfbVencryptX509None) {
- $fake_type = "None";
- } elsif ($sub_type == $rfbVencryptX509Vnc) {
- $fake_type = "VncAuth";
- } elsif ($sub_type == $rfbVencryptX509Plain) {
- $fake_type = "None";
- $plain = 1;
- }
- if ($plain) {
- if (!open(W, ">$handshake_file")) {
- unlink($handshake_file);
- die "pproxy: vencrypt_viewer_bridge[$$]: $handshake_file $!\n";
- }
- print W <<"END";
-
- proc print_out {} {
- global user pass env
-
- if [info exists env(SSVNC_UP_DEBUG)] {
- toplevel .b
- button .b.b -text "user=\$user pass=\$pass" -command {destroy .b}
- pack .b.b
- update
- tkwait window .b
- }
-
- if [info exists env(SSVNC_UP_FILE)] {
- set fh ""
- catch {set fh [open \$env(SSVNC_UP_FILE) w]}
- if {\$fh != ""} {
- puts \$fh user=\$user\\npass=\$pass
- flush \$fh
- close \$fh
- return
- }
- }
- puts stdout user=\$user\\npass=\$pass
- flush stdout
- }
-
- proc center_win {w} {
- 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]
-
- wm geometry \$w +\$x+\$y
- wm deiconify \$w
- update
- }
-
- wm withdraw .
-
- global env
- set up {}
- if [info exists env(SSVNC_UNIXPW)] {
- set rm 0
- set up \$env(SSVNC_UNIXPW)
- if [regexp {^rm:} \$up] {
- set rm 1
- regsub {^rm:} \$up {} up
- }
- if [file exists \$up] {
- set fh ""
- set f \$up
- catch {set fh [open \$up r]}
- if {\$fh != ""} {
- gets \$fh u
- gets \$fh p
- close \$fh
- set up "\$u@\$p"
- }
- if {\$rm} {
- catch {file delete \$f}
- }
- }
- } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] {
- set up \$env(SSVNC_VENCRYPT_USERPASS)
- }
- #puts stderr up=\$up
- if {\$up != ""} {
- if [regexp {@} \$up] {
- global user pass
- set user \$up
- set pass \$up
- regsub {@.*\$} \$user "" user
- regsub {^[^@]*@} \$pass "" pass
- print_out
- exit
- }
- }
-
- wm title . {VeNCrypt Viewer Bridge User/Pass}
-
- set user {}
- set pass {}
-
- label .l -text {SSVNC VeNCrypt Viewer Bridge}
-
- frame .f0
- frame .f0.fL
- label .f0.fL.la -text {Username: }
- label .f0.fL.lb -text {Password: }
-
- pack .f0.fL.la .f0.fL.lb -side top
-
- frame .f0.fR
- entry .f0.fR.ea -width 24 -textvariable user
- entry .f0.fR.eb -width 24 -textvariable pass -show *
-
- pack .f0.fR.ea .f0.fR.eb -side top -fill x
-
- pack .f0.fL -side left
- pack .f0.fR -side right -expand 1 -fill x
-
- button .no -text Cancel -command {destroy .}
- button .ok -text Done -command {print_out; destroy .}
-
- center_win .
- pack .l .f0 .no .ok -side top -fill x
- update
- wm deiconify .
-
- bind .f0.fR.ea <Return> {focus .f0.fR.eb}
- bind .f0.fR.eb <Return> {print_out; destroy .}
- focus .f0.fR.ea
-
- wm resizable . 1 0
- wm minsize . [winfo reqwidth .] [winfo reqheight .]
-END
- close W;
-
- #system("cat $handshake_file");
- my $w = "wish";
- if ($ENV{WISH}) {
- $w = $ENV{WISH};
- }
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: prompt VencryptPlain user and passwd.\n";
- my $res = "";
- if (`uname` =~ /Darwin/) {
- my $mtmp = `mktemp /tmp/hsup.XXXXXX`;
- chomp $mtmp;
- system("env SSVNC_UP_FILE=$mtmp $w $handshake_file");
- $res = `cat $mtmp`;
- unlink $mtmp;
- } else {
- $res = `$w $handshake_file`;
- }
- my $user = "";
- my $pass = "";
- if ($res =~ /user=(\S*)/) {
- $user = $1;
- }
- if ($res =~ /pass=(\S*)/) {
- $pass = $1;
- }
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: sending VencryptPlain user and passwd.\n";
- my $ulen = pack("C", length($user));
- my $plen = pack("C", length($pass));
- # (note this should be MSB, network byte order...)
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $ulen, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $u0, 1);
- syswrite($server_sock, $plen, 1);
- syswrite($server_sock, $user, length($user));
- syswrite($server_sock, $pass, length($pass));
- }
- unlink($handshake_file);
-
- my $ft = 0;
- if ($fake_type eq "None") {
- $ft = 1;
- } elsif ($fake_type eq "VncAuth") {
- $ft = 2;
- } else {
- die "pproxy: vencrypt_viewer_bridge[$$]: unknown fake type: $fake_type\n";
- }
- my $fp = pack("C", $ft);
- if ($viewer_major > 3 || $viewer_minor >= 7) {
- syswrite($viewer_sock, $u1, 1);
- syswrite($viewer_sock, $fp, 1);
- my $cr;
- sysread($viewer_sock, $cr, 1);
- $cr = unpack("C", $cr);
- if ($cr != $ft) {
- die "pproxy: vencrypt_viewer_bridge[$$]: client selected wrong type: $cr / $ft\n";
- }
- } else {
- print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n";
- # send 4 bytes sect type to viewer:
- # (note this should be MSB, network byte order...)
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $u0, 1);
- syswrite($viewer_sock, $fp, 1);
- if ($ft == 1) {
- # even None has security result, so read it here and discard it.
- my $sr = "";
- sysread($server_sock, $sr, 4);
- }
- }
- }
-
- $listen_handle = $viewer_sock;
- $sock = $server_sock;
-
- xfer_both();
-}
-'
- # '
- # xpg_echo will expand \n \r, etc.
- # try to unset and then test for it.
- if type shopt > /dev/null 2>&1; then
- shopt -u xpg_echo >/dev/null 2>&1
- fi
- v='print STDOUT "abc\n";'
- echo "$v" > $tf
- chmod 700 $tf
-
- lc=`wc -l $tf | awk '{print $1}'`
- if [ "X$lc" = "X1" ]; then
- echo "$cod" > $tf
- else
- printf "%s" "$cod" > $tf
- echo "" >> $tf
- fi
- # prime perl
- perl -e 'use IO::Socket::INET; select(undef, undef, undef, 0.01)' >/dev/null 2>&1
-}
-
-# make_tcert is no longer invoked via the ssvnc gui (Listen mode).
-# make_tcert is for testing only now via -mycert BUILTIN
-make_tcert() {
- tcert="/tmp/ss_vnc_viewer_tcert${RANDOM}.$$"
- tcert=`mytmp "$tcert"`
- cat > $tcert <<END
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAvkfXxb0wcxgrjV2ziFikjII+ze8iKcTBt47L0GM/c21efelN
-+zZpJUUXLu4zz8Ryq8Q+sQgfNy7uTOpN9bUUaOk1TnD7gaDQnQWiNHmqbW2kL+DS
-OKngJVPo9dETAS8hf7+D1e1DBZxjTc1a4RQqWJixwpYj99ixWzu8VC2m/xXsjvOs
-jp4+DLBB490nbkwvstmhmiWm1CmI5O5xOkgioVNQqHvQMdVKOSz9PpbjvZiRX1Uo
-qoMrk+2NOqwP90TB35yPASXb9zXKpO7DLhkube+yYGf+yk46aD707L07Eb7cosFP
-S84vNZ9gX7rQ0UOwm5rYA/oZTBskgaqhtIzkLwIDAQABAoIBAD4ot/sXt5kRn0Ca
-CIkU9AQWlC+v28grR2EQW9JiaZrqcoDNUzUqbCTJsi4ZkIFh2lf0TsqELbZYNW6Y
-6AjJM7al4E0UqYSKJTv2WCuuRxdiRs2BMwthqyBmjeanev7bB6V0ybt7u3Y8xU/o
-MrTuYnr4vrEjXPKdLirwk7AoDbKsRXHSIiHEIBOq1+dUQ32t36ukdnnza4wKDLZc
-PKHiCdCk/wOGhuDlxD6RspqUAlRnJ8/aEhrgWxadFXw1hRhRsf/v1shtB0T3DmTe
-Jchjwyiw9mryb9JZAcKxW+fUc4EVvj6VdQGqYInQJY5Yxm5JAlVQUJicuuJEvn6A
-rj5osQECgYEA552CaHpUiFlB4HGkjaH00kL+f0+gRF4PANCPk6X3UPDVYzKnzmuu
-yDvIdEETGFWBwoztUrOOKqVvPEQ+kBa2+DWWYaERZLtg2cI5byfDJxQ3ldzilS3J
-1S3WgCojqcsG/hlxoQJ1dZFanUy/QhUZ0B+wlC+Zp1Q8AyuGQvhHp68CgYEA0lBI
-eqq2GGCdJuNHMPFbi8Q0BnX55LW5C1hWjhuYiEkb3hOaIJuJrqvayBlhcQa2cGqp
-uP34e9UCfoeLgmoCQ0b4KpL2NGov/mL4i8bMgog4hcoYuIi3qxN18vVR14VKEh4U
-RLk0igAYPU+IK2QByaQlBo9OSaKkcfm7U1/pK4ECgYAxr6VpGk0GDvfF2Tsusv6d
-GIgV8ZP09qSLTTJvvxvF/lQYeqZq7sjI5aJD5i3de4JhpO/IXQJzfZfWOuGc8XKA
-3qYK/Y2IqXXGYRcHFGWV/Y1LFd55mCADHlk0l1WdOBOg8P5iRu/Br9PbiLpCx9oI
-vrOXpnp03eod1/luZmqguwKBgQCWFRSj9Q7ddpSvG6HCG3ro0qsNsUMTI1tZ7UBX
-SPogx4tLf1GN03D9ZUZLZVFUByZKMtPLX/Hi7K9K/A9ikaPrvsl6GEX6QYzeTGJx
-3Pw0amFrmDzr8ySewNR6/PXahxPEuhJcuI31rPufRRI3ZLah3rFNbRbBFX+klkJH
-zTnoAQKBgDbUK/aQFGduSy7WUT7LlM3UlGxJ2sA90TQh4JRQwzur0ACN5GdYZkqM
-YBts4sBJVwwJoxD9OpbvKu3uKCt41BSj0/KyoBzjT44S2io2tj1syujtlVUsyyBy
-/ca0A7WBB8lD1D7QMIhYUm2O9kYtSCLlUTHt5leqGaRG38DqlX36
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIDzDCCArQCCQDSzxzxqhyqLzANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMC
-VVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjETMBEG
-A1UEChMKTXkgQ29tcGFueTEcMBoGA1UECxMTUHJvZHVjdCBEZXZlbG9wbWVudDEZ
-MBcGA1UEAxMQd3d3Lm5vd2hlcmUubm9uZTEhMB8GCSqGSIb3DQEJARYSYWRtaW5A
-bm93aGVyZS5ub25lMB4XDTA3MDMyMzE4MDc0NVoXDTI2MDUyMjE4MDc0NVowgacx
-CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZC
-b3N0b24xEzARBgNVBAoTCk15IENvbXBhbnkxHDAaBgNVBAsTE1Byb2R1Y3QgRGV2
-ZWxvcG1lbnQxGTAXBgNVBAMTEHd3dy5ub3doZXJlLm5vbmUxITAfBgkqhkiG9w0B
-CQEWEmFkbWluQG5vd2hlcmUubm9uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAL5H18W9MHMYK41ds4hYpIyCPs3vIinEwbeOy9BjP3NtXn3pTfs2aSVF
-Fy7uM8/EcqvEPrEIHzcu7kzqTfW1FGjpNU5w+4Gg0J0FojR5qm1tpC/g0jip4CVT
-6PXREwEvIX+/g9XtQwWcY03NWuEUKliYscKWI/fYsVs7vFQtpv8V7I7zrI6ePgyw
-QePdJ25ML7LZoZolptQpiOTucTpIIqFTUKh70DHVSjks/T6W472YkV9VKKqDK5Pt
-jTqsD/dEwd+cjwEl2/c1yqTuwy4ZLm3vsmBn/spOOmg+9Oy9OxG+3KLBT0vOLzWf
-YF+60NFDsJua2AP6GUwbJIGqobSM5C8CAwEAATANBgkqhkiG9w0BAQQFAAOCAQEA
-vGomHEp6TVU83X2EBUgnbOhzKJ9u3fOI/Uf5L7p//Vxqow7OR1cguzh/YEzmXOIL
-ilMVnzX9nj/bvcLAuqEP7MR1A8f4+E807p/L/Sf49BiCcwQq5I966sGKYXjkve+T
-2GTBNwMSq+5kLSf6QY8VZI+qnrAudEQMeJByQhTZZ0dH8Njeq8EGl9KUio+VWaiW
-CQK6xJuAvAHqa06OjLmwu1fYD4GLGSrOIiRVkSXV8qLIUmzxdJaIRznkFWsrCEKR
-wAH966SAOvd2s6yOHMvyDRIL7WHxfESB6rDHsdIW/yny1fBePjv473KrxyXtbz7I
-dMw1yW09l+eEo4A7GzwOdw==
------END CERTIFICATE-----
-END
- chmod 600 $tcert
- echo "$tcert"
-}
-
-Kecho() {
- NO_KECHO=1
- if [ "X$USER" = "Xrunge" -a "X$NO_KECHO" = "X" ]; then
- echo "dbg: $*"
- fi
-}
-
-NHAFL_warning() {
- echo ""
- echo "** Warning: For the proxy: $proxy"
- echo "** Warning: the ssh(1) option: $ssh_NHAFL"
- echo "** Warning: will be used to avoid frequent 'ssh key has changed for localhost'"
- echo "** Warning: dialogs and connection failures (for example, ssh will exit asking"
- echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)"
- echo "** Warning: "
- echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible."
- echo "** Warning: For chained ssh connections the first ssh leg is secure but the"
- echo "** Warning: 2nd ssh leg is vulnerable. For an ssh connection going through"
- echo "** Warning: a HTTP or SOCKS proxy the ssh connection is vulnerable."
- echo "** Warning: "
- echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable"
- echo "** Warning: using the NoHostAuthenticationForLocalhost=yes ssh option."
- echo "** Warning: "
- echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:"
- echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set"
- echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts"
- echo "** Warning: file. That file holds the 'localhost' cert for this specific"
- echo "** Warning: connection. This yields a both secure and convenient solution."
- echo ""
-}
-
-space_expand() {
- str=`echo "$1" | sed -e 's/%SPACE/ /g' -e 's/%TAB/\t/g'`
- echo "$str"
-}
-
-# handle ssh case:
-#
-if [ "X$use_ssh" = "X1" ]; then
- #
- # USING SSH
- #
- ssh_port="22"
- ssh_host="$host"
- vnc_host="$localhost"
- ssh_UKHF=""
- localhost_extra=""
- # let user override ssh via $SSH
- ssh=${SSH:-"ssh -x"}
-
- sshword=`echo "$ssh" | awk '{print $1}'`
- if [ "X$sshword" != "X" ]; then
- if [ -x "$sshword" ]; then
- :
- elif type "$sshword" > /dev/null 2>&1; then
- :
- else
- echo ""
- echo "*********************************************************"
- echo "** Problem finding the SSH command '$sshword': **"
- echo ""
- type "$sshword"
- echo ""
- echo "** Perhaps you need to install the SSH client package. **"
- echo "*********************************************************"
- echo ""
- sleep 5
- fi
- fi
-
- ssh_NHAFL="-o NoHostAuthenticationForLocalhost=yes"
- if [ "X$SSVNC_SSH_LOCALHOST_AUTH" = "X1" ]; then
- ssh_NHAFL=""
- fi
- if [ "X$SSVNC_KNOWN_HOSTS_FILE" != "X" ]; then
- ssh_NHAFL=""
-
- ssh_UKHF="-o UserKnownHostsFile=$SSVNC_KNOWN_HOSTS_FILE"
- ssh_args="$ssh_args $ssh_UKHF"
- if [ ! -f "$SSVNC_KNOWN_HOSTS_FILE" ]; then
- touch "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1
- fi
- chmod 600 "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1
- fi
- did_ssh_NHAFL=""
-
- if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then
- SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD"
- fi
- if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then
- echo ""
- echo "SSVNC_LIM_ACCEPT_PRELOAD=$SSVNC_LIM_ACCEPT_PRELOAD"
- fi
-
- if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" -a -f "$SSVNC_LIM_ACCEPT_PRELOAD" ]; then
- plvar=LD_PRELOAD
- if uname | grep Darwin >/dev/null; then
- plvar="DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES"
- fi
- ssh="env $plvar=$SSVNC_LIM_ACCEPT_PRELOAD $ssh"
- else
- SSVNC_LIM_ACCEPT_PRELOAD=""
- fi
-
- ssh_vencrypt_proxy=""
- # We handle vencrypt for SSH+SSL mode.
- if echo "$proxy" | grep 'vencrypt://' > /dev/null; then
- proxynew=""
- for part in `echo "$proxy" | tr ',' ' '`
- do
- if echo "$part" | egrep -i '^vencrypt://' > /dev/null; then
- ssh_vencrypt_proxy=$part
- else
- if [ "X$proxynew" = "X" ]; then
- proxynew="$part"
- else
- proxynew="$proxynew,$part"
- fi
- fi
- done
- proxy=$proxynew
- fi
- Kecho ssh_vencrypt_proxy=$ssh_vencrypt_proxy
-
- # note that user must supply http:// for web proxy in SSH and SSH+SSL.
- # No xxxx:// implies ssh server+port.
- #
- if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then
- # Handle Web or SOCKS proxy(ies) for the initial connect.
- Kecho host=$host
- Kecho port=$port
- pproxy=""
- sproxy1=""
- sproxy_rest=""
- for part in `echo "$proxy" | tr ',' ' '`
- do
- Kecho proxy_part=$part
- if [ "X$part" = "X" ]; then
- continue
- elif echo "$part" | egrep -i '^(http|https|socks|socks4|socks5)://' > /dev/null; then
- pproxy="$pproxy,$part"
- else
- if [ "X$sproxy1" = "X" ]; then
- sproxy1="$part"
- else
- sproxy_rest="$sproxy_rest,$part"
- fi
- fi
- done
- pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
- sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
-
- Kecho pproxy=$pproxy
- Kecho sproxy1=$sproxy1
- Kecho sproxy_rest=$sproxy_rest
-
- sproxy1_host=""
- sproxy1_port=""
- sproxy1_user=""
-
- if [ "X$sproxy1" != "X" ]; then
- # XXX fix ipv6 ip adder here and below.
- sproxy1_host=`echo "$sproxy1" | awk -F: '{print $1}'`
- sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'`
- sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'`
- if [ "X$sproxy1_host" = "X" ]; then
- sproxy1_host=$sproxy1_user
- sproxy1_user=""
- else
- sproxy1_user="${sproxy1_user}@"
- fi
- sproxy1_port=`echo "$sproxy1" | awk -F: '{print $2}'`
- if [ "X$sproxy1_port" = "X" ]; then
- sproxy1_port="22"
- fi
- else
- sproxy1_host=`echo "$host" | awk -F: '{print $1}'`
- sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'`
- sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'`
- if [ "X$sproxy1_host" = "X" ]; then
- sproxy1_host=$sproxy1_user
- sproxy1_user=""
- else
- sproxy1_user="${sproxy1_user}@"
- fi
- sproxy1_port=`echo "$host" | awk -F: '{print $2}'`
- if [ "X$sproxy1_port" = "X" ]; then
- sproxy1_port="22"
- fi
- fi
-
- Kecho sproxy1_host=$sproxy1_host
- Kecho sproxy1_port=$sproxy1_port
- Kecho sproxy1_user=$sproxy1_user
-
- ptmp="/tmp/ss_vncviewer_ssh${RANDOM}.$$.pl"
- ptmp=`mytmp "$ptmp"`
- PPROXY_REMOVE=1; export PPROXY_REMOVE
- proxy=$pproxy
- port_save=$port
- host_save=$host
- if [ "X$sproxy1_host" != "X" ]; then
- host=$sproxy1_host
- fi
- if [ "X$sproxy1_port" != "X" ]; then
- port=$sproxy1_port
- fi
- host=`echo "$host" | sed -e 's/^.*@//'`
- port=`echo "$port" | sed -e 's/^.*://'`
- pcode "$ptmp"
- port=$port_save
- host=$host_save
-
- nd=`findfree 6600`
- PPROXY_LISTEN=$nd; export PPROXY_LISTEN
- # XXX no reverse forever PPROXY_LOOP_THYSELF ...
- $ptmp &
- sleep 1
- if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then
- NHAFL_warning
- ssh_args="$ssh_args $ssh_NHAFL"
- did_ssh_NHAFL=1
- fi
- sleep 1
- if [ "X$sproxy1" = "X" ]; then
- u=""
- if echo "$host" | grep '@' > /dev/null; then
- u=`echo "$host" | sed -e 's/@.*$/@/'`
- fi
-
- proxy="${u}$localhost:$nd"
- else
- proxy="${sproxy1_user}$localhost:$nd"
- fi
- localhost_extra=".2"
- if [ "X$sproxy_rest" != "X" ]; then
- proxy="$proxy,$sproxy_rest"
- fi
- Kecho proxy=$proxy
- fi
-
- if echo "$proxy" | grep "," > /dev/null; then
-
- proxy1=`echo "$proxy" | awk -F, '{print $1}'`
- proxy2=`echo "$proxy" | awk -F, '{print $2}'`
-
- # user1@gw1.com:port1,user2@ws2:port2
- ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'`
- ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'`
- if [ "X$ssh_port1" != "X" ]; then
- ssh_port1="-p $ssh_port1"
- fi
- ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'`
- ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'`
- ssh_host2=`echo "$ssh_host2" | awk -F@ '{print $2}'`
- if [ "X$ssh_host2" = "X" ]; then
- ssh_host2=$ssh_user2
- ssh_user2=""
- else
- ssh_user2="${ssh_user2}@"
- fi
- ssh_port2=`echo "$proxy2" | awk -F: '{print $2}'`
- if [ "X$ssh_port2" = "X" ]; then
- ssh_port2="22"
- fi
- proxport=`findfree 3500`
- if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then
- NHAFL_warning
- did_ssh_NHAFL=1
- sleep 1
- fi
- echo
- echo "Running 1st ssh proxy:"
- ukhf=""
- if [ "X$ssh_UKHF" != "X" ]; then
- ukhf="$ssh_UKHF$localhost_extra"
- fi
- if echo "$ssh_host1" | grep '%' > /dev/null; then
- uath=`space_expand "$ssh_host1"`
- else
- uath="$ssh_host1"
- fi
- echo "$ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 \"$uath\" \"sleep 30\""
- echo ""
- $ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 "$uath" "sleep 30"
- ssh_args="$ssh_args $ssh_NHAFL"
- sleep 1
- stty sane
- proxy="${ssh_user2}$localhost:$proxport"
- fi
-
- if [ "X$proxy" != "X" ]; then
- ssh_port=`echo "$proxy" | awk -F: '{print $2}'`
- if [ "X$ssh_port" = "X" ]; then
- ssh_port="22"
- fi
- ssh_host=`echo "$proxy" | awk -F: '{print $1}'`
- vnc_host="$host"
- fi
-
- echo ""
- echo "Running ssh:"
- sz=`echo "$ssh_cmd" | wc -c`
- if [ "$sz" -gt 300 ]; then
- info="..."
- else
- info="$ssh_cmd"
- fi
-
- C=""
- if [ "X$SS_VNCVIEWER_USE_C" != "X" ]; then
- C="-C"
- fi
-
- getport=""
- teeport=""
- if echo "$ssh_cmd" | egrep "(PORT=|P=) " > /dev/null; then
- getport=1
- if echo "$ssh_cmd" | egrep "P= " > /dev/null; then
- teeport=1
- fi
-
- PORT=""
- ssh_cmd=`echo "$ssh_cmd" | sed -e 's/PORT=[ ]*//' -e 's/P=//'`
- SSVNC_NO_ENC_WARN=1
- if [ "X$use_sshssl" = "X" ]; then
- direct_connect=1
- fi
- fi
- if [ "X$getport" != "X" ]; then
- ssh_redir="-D ${use}"
- elif [ "X$reverse" = "X" ]; then
- ssh_redir="-L ${use}:${vnc_host}:${port}"
- else
- ssh_redir="-R ${port}:${vnc_host}:${use}"
- fi
- pmark=`sh -c 'echo $$'`
-
- # the -t option actually speeds up typing response via VNC!!
- if [ "X$ssh_port" = "X22" ]; then
- ssh_port=""
- else
- ssh_port="-p $ssh_port"
- fi
-
- if echo "$ssh_host" | grep '%' > /dev/null; then
- uath=`space_expand "$ssh_host"`
- else
- uath="$ssh_host"
- fi
- if [ "X$SS_VNCVIEWER_SSH_ONLY" != "X" ]; then
- echo "$ssh -x $ssh_port $targ $C $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x $ssh_port $targ $C $ssh_args "$uath" "$ssh_cmd"
- exit $?
-
- elif [ "X$SS_VNCVIEWER_NO_F" != "X" ]; then
- echo "$ssh -x $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd"
- rc=$?
-
- elif [ "X$getport" != "X" ]; then
- tport=/tmp/ss_vncviewer_tport${RANDOM}.$$
- tport=`mytmp "$tport"`
- tport2=/tmp/ss_vncviewer_tport2${RANDOM}.$$
- tport2=`mytmp "$tport2"`
-
- if [ "X$rsh" != "X1" ]; then
- if echo "$ssh_cmd" | grep "sudo " > /dev/null; then
- echo ""
- echo "Initial ssh with 'sudo id' to prime sudo so hopefully the next one"
- echo "will require no password..."
- echo ""
- targ="-t"
- $ssh -x $ssh_port $targ $ssh_args "$uath" "sudo id; tty"
- echo ""
- fi
- echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" > $tport 2> $tport2
- if [ "X$teeport" = "X1" ]; then
- tail -f $tport 1>&2 &
- tail_pid=$!
- tail -f $tport2 1>&2 &
- tail_pid2=$!
- fi
- rc=$?
- else
- rsh_setup
- echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\""
- echo ""
- rsh $ul "$ssh_host" "$ssh_cmd" > $tport &
- sleep 1
- rc=0
- fi
-
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
- fi
-
- stty sane
- i=0
- if type perl > /dev/null 2>&1; then
- imax=50
- sleepit="perl -e 'select(undef, undef, undef, 0.20)'"
- else
- imax=10
- sleepit="sleep 1"
- fi
- while [ $i -lt $imax ]; do
- #echo $sleepit
- eval $sleepit
- PORT=`grep "^PORT=" $tport | tr '\r' ' ' | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g' -e 's/ *$//'`
- if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
- break
- fi
- vnss=`sed -e 's/\r//g' $tport $tport2 | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1 | awk '{print $NF}'`
- if [ "X$vnss" != "X" ]; then
- PORT=`echo "$vnss" | awk -F: '{print $2}'`
- if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
- if [ $PORT -lt 100 ]; then
- PORT=`expr $PORT + 5900`
- fi
- fi
- if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
- vnss=`sed -e 's/\r//g' $tport | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1`
- echo "vncserver string: $vnss" 1>&2
- break
- fi
- fi
- i=`expr $i + 1`
- done
-
- echo "found: PORT='$PORT'" 1>&2
- lh6=""
- if [ "X$SSVNC_PORT_IPV6" != "X" ]; then
- lh6=1
- elif egrep 'Info: listening on IPv6 only|Info: listening only on IPv6' $tport > /dev/null; then
- lh6=1
- fi
- if [ "X$lh6" = "X1" ]; then
- echo "set SOCKS5 localhost to ::1" 1>&2
- fi
- rm -f $tport $tport2
- if [ "X$rsh" = "X1" ]; then
- rsh_viewer "$@"
- exit $?
- fi
- PPROXY_SOCKS=5
- if [ "X$SSVNC_SOCKS5" != "X" ]; then
- PPROXY_SOCKS=5
- elif [ "X$SSVNC_SOCKS4" != "X" ]; then
- PPROXY_SOCKS=1
- fi
- export PPROXY_SOCKS
- if [ "X$lh6" = "X" ]; then
- host="$localhost"
- else
- host="::1"
- fi
- port="$PORT"
- proxy="$localhost:$use"
-
- else
- if [ "X$rsh" != "X1" ]; then
- echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\""
- echo ""
- $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd"
- rc=$?
- else
- rsh_setup
- echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\""
- echo ""
- rsh $ul "$ssh_host" "$ssh_cmd" &
- sleep 1
- PORT=$port
- rsh_viewer "$@"
- exit $?
- fi
- fi
-
- if [ "$rc" != "0" ]; then
- echo ""
- echo "ssh to \"$uath\" failed."
- exit 1
- fi
- stty sane
-
- c=0
- pssh=""
- while [ $c -lt 40 ]
- do
- p=`expr $pmark + $c`
- pout=`ps -p "$p" 2>/dev/null | grep -v '^[ ]*PID' | sed -e 's/-L.*$//' -e 's/-x .*$//'`
- if echo "$pout" | grep "ssh" > /dev/null; then
- if echo "$pout" | egrep -i 'ssh.*(-add|-agent|-ask|-keygen|-argv0|vnc)' >/dev/null; then
- :
- elif echo "$pout" | egrep -i 'scp|sshd' >/dev/null; then
- :
- else
- pssh=$p
- break
- fi
- fi
- c=`expr $c + 1`
- done
- if [ "X$getport" != "X" ]; then
- :
- elif [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ] ; then
- sleep 2
- elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then
- #echo T sleep 1
- sleep 1
- elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then
- #echo T sleep 2
- sleep 2
- else
- # let any command get started a bit.
- #echo T sleep 5
- sleep 5
- fi
- echo ""
- #reset
- stty sane
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
- fi
- echo "ssh_pid='$pssh'"; echo
- if [ "X$use_sshssl" = "X" -a "X$getport" = "X" ]; then
- if [ "X$SSVNC_EXTRA_COMMAND" != "X" ]; then
- (sh -c "$SSVNC_EXTRA_COMMAND") &
- echo "($SSVNC_EXTRA_COMMAND) &"; echo
- fi
- echo "Running viewer:"
-
- trap "final" 0 2 15
- if [ "X$reverse" = "X" ]; then
- echo "$VNCVIEWERCMD" "$@" $localhost:$N
- echo ""
- $VNCVIEWERCMD "$@" $localhost:$N
- if [ $? != 0 ]; then
- echo "vncviewer command failed: $?"
- if [ "X$secondtry" = "X1" ]; then
- sleep 2
- $VNCVIEWERCMD "$@" $localhost:$N
- fi
- fi
- else
- echo ""
- echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
- echo ""
- N2=$N
- if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
- N2=`echo "$N2" | sed -e 's/://g'`
- if [ $N2 -le 200 ]; then
- N2=`expr $N2 + 5500`
- fi
- fi
- echo "$VNCVIEWERCMD" "$@" -listen $N2
- echo ""
- $VNCVIEWERCMD "$@" -listen $N2
- fi
-
- exit $?
- else
- use2=`findfree 5960`
- host0=$host
- port0=$port
- host=$localhost
- port=$use
- use=$use2
- N=`expr $use - 5900`
- if [ "X$getport" != "X" ]; then
- host="$host0"
- port="$port0"
- else
- proxy=""
- fi
- if [ "X$ssh_vencrypt_proxy" != "X" ]; then
- ssh_vencrypt_proxy="vencrypt://$host:$port"
- if [ "X$proxy" = "X" ]; then
- proxy=$ssh_vencrypt_proxy
- else
- proxy="$proxy,$ssh_vencrypt_proxy"
- fi
- Kecho "proxy_now=$proxy"
- unset PPROXY_LISTEN
- fi
- fi
-fi
-
-if [ "X$stunnel_set_here" = "X1" -a "X$showcert" = "X" ]; then
- if type $STUNNEL > /dev/null 2>&1; then
- :
- else
- echo ""
- echo "***************************************************************"
- echo "** Problem finding the Stunnel command '$STUNNEL': **"
- echo ""
- type $STUNNEL
- echo ""
- echo "** Perhaps you need to install the stunnel/stunnel4 package. **"
- echo "***************************************************************"
- echo ""
- sleep 5
- fi
-fi
-
-# create the stunnel config file:
-if [ "X$verify" != "X" ]; then
- if [ -d $verify ]; then
- verify="CApath = $verify"
- else
- verify="CAfile = $verify"
- fi
- verify="$verify
-verify = 2"
-fi
-if [ "X$SSVNC_STUNNEL_VERIFY3" != "X" ]; then
- verify=`echo "$verify" | sed -e 's/verify = 2/verify = 3/'`
-fi
-if [ "X$mycert" != "X" ]; then
- cert="cert = $mycert"
-fi
-if [ "X$crl" != "X" ]; then
- if [ -d $crl ]; then
- crl="CRLpath = $crl"
- else
- crl="CRLfile = $crl"
- fi
-fi
-
-if [ "X$showcert" = "X1" ]; then
- if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then
- :
- elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then
- :
- elif [ "X$ipv6" = "X1" -a "X$proxy" = "X" ]; then
- proxy="ipv6://$host:$port"
- fi
-fi
-
-if [ "X$direct_connect" != "X" -a "X$STUNNEL_LISTEN" != "X" ]; then
- proxy=reverse_direct
-fi
-
-ptmp=""
-if [ "X$proxy" != "X" ]; then
- ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl"
- ptmp=`mytmp "$ptmp"`
- PPROXY_REMOVE=1; export PPROXY_REMOVE
- pcode "$ptmp"
- if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then
- if uname | egrep 'Darwin|SunOS' >/dev/null; then
- vout=`echo "$proxy" | grep -i vencrypt`
- if [ "X$vout" != "X" -a "X$reverse" = "X1" ]; then
- # need to exec for reverse vencrypt
- connect="exec = $ptmp"
- else
- # on mac and solaris we need to listen on socket instead of stdio:
- nd=`findfree 6700`
- PPROXY_LISTEN=$nd
- export PPROXY_LISTEN
- if [ "X$reverse" = "X" ]; then
- $ptmp &
- fi
- sleep 2
- host="$localhost"
- port="$nd"
- connect="connect = $localhost:$nd"
- fi
- else
- # otherwise on unix we can exec it:
- connect="exec = $ptmp"
- fi
- else
- connect="exec = $ptmp"
- fi
-else
- connect="connect = $host:$port"
-fi
-
-# handle showcert case:
-#
-if [ "X$showcert" = "X1" ]; then
- if [ "X$proxy" != "X" ]; then
- PPROXY_LISTEN=$use
- export PPROXY_LISTEN
- if [ "X$SS_DEBUG" != "X" ]; then
- $ptmp &
- else
- $ptmp 2>/dev/null &
- fi
- sleep 1
- more_sleep=1
- if uname | grep Linux > /dev/null; then
- if netstat -ant | grep LISTEN | grep "127.0.0.1:$use" > /dev/null; then
- more_sleep=""
- fi
- elif uname | grep SunOS > /dev/null; then
- if netstat -an -f inet -P tcp | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then
- more_sleep=""
- fi
- elif uname | egrep -i 'bsd|darwin' > /dev/null; then
- if netstat -ant -f inet | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then
- more_sleep=""
- fi
- fi
- if [ "X$more_sleep" = "X1" ]; then
- sleep 1
- fi
- host="$localhost"
- port="$use"
- fi
- cipher_args=""
- if [ "X$ciphers" != "X" ]; then
- cipher_args=`echo "$ciphers" | sed -e 's/ciphers=/-cipher /'`
- fi
- if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then
- :
- elif type openssl > /dev/null 2>&1; then
- :
- else
- echo ""
- echo "********************************************************"
- echo "** Problem finding the OpenSSL command 'openssl': **"
- echo ""
- type openssl 2>&1
- echo ""
- echo "** Perhaps you need to install the 'openssl' package. **"
- echo "********************************************************"
- echo ""
- fi
- #echo "openssl s_client $cipher_args -connect $host:$port"
- if [ "X$reverse" = "X" ]; then
- if type host > /dev/null 2>/dev/null; then
- host $host >/dev/null 2>&1
- host $host >/dev/null 2>&1
- fi
- timeout=15
- if [ "X$SSVNC_FETCH_TIMEOUT" != "X" ]; then
- timeout=$SSVNC_FETCH_TIMEOUT
- fi
- if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then
- if type pkill >/dev/null 2>&1; then
- (sleep $timeout; if kill -0 $$; then pkill -TERM -f "ultravnc_dsm_helper.*$host.*$port"; fi) >/dev/null 2>&1 &
- fi
- ultravnc_dsm_helper showcert $host:$port 2>&1
- else
- if type pkill >/dev/null 2>&1; then
- (sleep $timeout; if kill -0 $$; then pkill -TERM -f "openssl.*s_client.*$host.*$port"; fi) >/dev/null 2>&1 &
- fi
- openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null
- fi
- rc=$?
- else
- tcert=""
- if [ "X$mycert" = "X" ]; then
- tcert=`make_tcert`
- cert_args="-cert $tcert -CAfile $tcert"
- else
- cert_args="-cert $mycert -CAfile $mycert"
- fi
- tmp_out=/tmp/showcert_out${RANDOM}.$$
- tmp_out=`mytmp "$tmp_out"`
- tmp_err=/tmp/showcert_err${RANDOM}.$$
- tmp_err=`mytmp "$tmp_err"`
-
- #echo "openssl s_server $cipher_args $cert_args -accept $port -verify 2 > $tmp_out 2> $tmp_err" 1>&2
-
- # assume we have perl:
- check_perl perl
-
- perl -e "
- \$p = open(O, \"|openssl s_server $cipher_args $cert_args -accept $port -verify 2 1>$tmp_out 2> $tmp_err\");
- exit 1 unless \$p;
- while (1) {
- sleep 1;
- if (!open(F, \"<$tmp_out\")) {
- kill \$p;
- exit 1;
- }
- while (<F>) {
- if (/RFB 00/) {
- fsleep(0.25);
- print O \"RFB 000.000\\n\";
- fsleep(1.00);
- kill \$p;
- fsleep(0.25);
- exit 0;
- }
- }
- close F;
- }
- sub fsleep {
- select(undef, undef, undef, shift);
- }
- ";
-
- echo ""
- cat $tmp_out
- echo ""
- echo "----2----"
- cat $tmp_err
- if grep BEGIN.CERTIFICATE $tmp_out >/dev/null; then
- rc=0
- else
- rc=1
- fi
-
- rm -f $tmp_out $tmp_err
- fi
- if [ "X$SSVNC_PREDIGESTED_HANDSHAKE" != "X" ]; then
- rm -f $SSVNC_PREDIGESTED_HANDSHAKE
- fi
- if [ "X$SSVNC_SHOWCERT_EXIT_0" = "X1" ]; then
- exit 0
- else
- exit $rc
- fi
-fi
-
-# handle direct connect case:
-#
-if [ "X$direct_connect" != "X" ]; then
- if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- SSVNC_NO_ENC_WARN=1
- echo ""
- echo "Using UltraVNC DSM Plugin key for encryption:"
- echo ""
- ustr=`echo "$SSVNC_ULTRA_DSM" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo " $ustr PORT HOST:PORT"
- echo ""
- elif [ "X$getport" = "X" ]; then
- echo ""
- echo "Running viewer for direct connection:"
- if echo X"$@" | grep chatonly > /dev/null; then
- :
- else
- echo ""
- echo "** WARNING: THERE WILL BE NO SSL OR SSH ENCRYPTION **"
- echo ""
- fi
- fi
- x=""
- if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then
- if [ "X$getport" = "X" ]; then
- sleep 1
- fi
- elif type printf > /dev/null 2>&1; then
- printf "Are you sure you want to continue? [y]/n "
- read x
- else
- echo -n "Are you sure you want to continue? [y]/n "
- read x
- fi
- if [ "X$x" = "Xn" ]; then
- exit 1
- fi
- echo ""
- if [ "X$ptmp" != "X" ]; then
- if [ "X$reverse" = "X" ]; then
- PPROXY_LISTEN=$use
- export PPROXY_LISTEN
- else
- if [ "X$proxy" = "Xreverse_direct" ]; then
- PPROXY_LISTEN="$STUNNEL_LISTEN:`expr 5500 + $disp`"
- PPROXY_DEST="$localhost:$use"
- PPROXY_PROXY="ipv6://$localhost:$use" # not always ipv6..
- export PPROXY_LISTEN PPROXY_DEST PPROXY_PROXY
- pps=1
- else
- PPROXY_REVERSE="$localhost:$use"
- export PPROXY_LISTEN
- pps=3
- fi
- if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
- PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself.${RANDOM}.$$"`
- export PPROXY_LOOP_THYSELF
- pps=2
- fi
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- pps=`expr $pps + $SSVNC_EXTRA_SLEEP`
- fi
- PPROXY_SLEEP=$pps; export PPROXY_SLEEP;
- PPROXY_KILLPID=+1; export PPROXY_KILLPID;
- fi
-
- $ptmp &
-
- if [ "X$reverse" = "X" ]; then
- #sleep 2
- #echo T sleep 1
- sleep 1
- fi
- host="$localhost"
- disp="$N"
- port=`expr $disp + 5900`
- fi
- if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "T sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
- fi
- if [ "X$SSVNC_EXTRA_COMMAND" != "X" ]; then
- (sh -c "$SSVNC_EXTRA_COMMAND") &
- echo "($SSVNC_EXTRA_COMMAND) &"; echo
- fi
- if [ "X$reverse" = "X" ]; then
- hostdisp="$host:$disp"
- if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- if [ "X$SSVNC_USE_OURS" = "X1" ]; then
- hostdisp="exec=$SSVNC_ULTRA_DSM 0 $host:$port"
- else
- pf=`findfree 5970`
- cmd="$SSVNC_ULTRA_DSM -$pf $host:$port"
- pf=`expr $pf - 5900`
- hostdisp="$localhost:$pf"
- ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo "Running:"
- echo
- echo "$ustr &"
- echo
- $cmd &
- dsm_pid=$!
- sleep 2
- fi
- fi
- hostdisp2=`echo "$hostdisp" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo "$VNCVIEWERCMD" "$@" "$hostdisp2"
- trap "final" 0 2 15
- echo ""
- $VNCVIEWERCMD "$@" "$hostdisp"
- if [ $? != 0 ]; then
- echo "vncviewer command failed: $?"
- if [ "X$secondtry" = "X1" ]; then
- sleep 2
- $VNCVIEWERCMD "$@" "$hostdisp"
- fi
- fi
- else
- echo ""
- echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
- echo ""
- trap "final" 0 2 15
- if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
- if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then
- echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN"
- echo " ends you must restart the Listening mode. You may also need to"
- echo " Press Ctrl-C to stop the viewer and restart for another connection."
- echo ""
- fi
- #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
- VNCVIEWER_LISTEN_LOCALHOST=1
- export VNCVIEWER_LISTEN_LOCALHOST
- dport=`expr 5500 + $disp`
- cmd="$SSVNC_ULTRA_DSM $dport $localhost:$use"
- ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'`
- echo "Running:"
- echo
- echo "$ustr &"
- echo
- if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then
- $cmd &
- dsm_pid=$!
- else
- while [ 1 ]; do $cmd; sleep 1; done &
- dsm_pid=$!
- fi
- sleep 2
- disp=$use
- if [ $disp -ge 5500 ]; then
- disp=`expr $disp - 5500`
- fi
- fi
- disp2=$disp
- if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
- disp2=`echo "$disp2" | sed -e 's/://g'`
- if [ $disp2 -le 200 ]; then
- disp2=`expr $disp2 + 5500`
- fi
- fi
- echo "$VNCVIEWERCMD" "$@" -listen $disp2
- echo ""
- $VNCVIEWERCMD "$@" -listen $disp2
- if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then
- rm -f $PPROXY_LOOP_THYSELF
- fi
- fi
- exit $?
-fi
-
-tmp_cfg=/tmp/ss_vncviewer${RANDOM}.$$
-tmp_cfg=`mytmp "$tmp_cfg"`
-
-stunnel_exec=""
-if [ "X$SSVNC_USE_OURS" != "X1" ]; then
- :
-elif echo $STUNNEL_EXTRA_SVC_OPTS | grep '#stunnel-exec' > /dev/null; then
- stunnel_exec="#"
-fi
-
-if [ "X$reverse" = "X" ]; then
-
- if echo "$proxy" | grep "^repeater://" > /dev/null; then
- if [ "X$cert" = "XBUILTIN" ]; then
- ttcert=`make_tcert`
- cert="cert = $ttcert"
- fi
- # Note for listen mode, an empty cert will cause stunnel to fail.
- # The ssvnc gui will have already taken care of this.
- fi
-
- cat > "$tmp_cfg" <<END
-foreground = yes
-pid =
-client = yes
-debug = $stunnel_debug
-$ciphers
-$STUNNEL_EXTRA_OPTS
-$STUNNEL_EXTRA_OPTS_USER
-$cert
-$crl
-$verify
-
-${stunnel_exec}[vnc_stunnel]
-${stunnel_exec}accept = $localhost:$use
-$connect
-$STUNNEL_EXTRA_SVC_OPTS
-$STUNNEL_EXTRA_SVC_OPTS_USER
-
-END
-
-else
- # REVERSE case:
-
- stunnel_exec="" # doesn't work for listening.
-
- p2=`expr 5500 + $N`
- connect="connect = $localhost:$p2"
- if [ "X$cert" = "XBUILTIN" ]; then
- ttcert=`make_tcert`
- cert="cert = $ttcert"
- fi
- # Note for listen mode, an empty cert will cause stunnel to fail.
- # The ssvnc gui will have already taken care of this.
-
-
- hloc=""
- if [ "X$use_ssh" = "X1" ]; then
- hloc="$localhost:"
- elif [ "X$STUNNEL_LISTEN" != "X" ]; then
- hloc="$STUNNEL_LISTEN:"
- fi
- if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
- hloc="$localhost:"
- pv=`findfree 5570`
- proxy="vencrypt:$pv:$port"
- port=$pv
- if [ "X$anondh_set" = "X1" ]; then
- # not needed for ANONDH in this mode
- #ciphers="ciphers = ADH:@STRENGTH"
- :
- fi
- fi
- cat > "$tmp_cfg" <<END
-foreground = yes
-pid =
-client = no
-debug = $stunnel_debug
-$ciphers
-$STUNNEL_EXTRA_OPTS
-$STUNNEL_EXTRA_OPTS_USER
-$cert
-$crl
-$verify
-
-[vnc_stunnel]
-accept = $hloc$port
-$connect
-$STUNNEL_EXTRA_SVC_OPTS
-$STUNNEL_EXTRA_SVC_OPTS_USER
-
-END
-
-fi
-
-echo ""
-echo "Using this stunnel configuration:"
-echo ""
-cat "$tmp_cfg" | uniq
-echo ""
-if egrep -i '^[ ]*(CApath|CAfile) =' "$tmp_cfg" > /dev/null ; then
- :
-else
- echo "** WARNING: THE STUNNEL CONFIG HAS NO SERVER CERTIFICATE SPECIFIED **"
- echo "** WARNING: (the CApath or CAfile stunnel option) THE VNC SERVER WILL **"
- echo "** WARNING: NOT BE AUTHENTICATED. A MAN-IN-THE-MIDDLE ATTACK IS POSSIBLE **"
- echo ""
-fi
-sleep 1
-
-if [ "X$stunnel_exec" = "X" ]; then
- echo ""
- echo "Running stunnel:"
- echo "$STUNNEL $tmp_cfg"
- st=`echo "$STUNNEL" | awk '{print $1}'`
- $st -help > /dev/null 2>&1
- $STUNNEL "$tmp_cfg" < /dev/tty > /dev/tty &
- stunnel_pid=$!
- echo ""
-
- # pause here to let the user supply a possible passphrase for the
- # mycert key:
- if [ "X$mycert" != "X" ]; then
- nsl=10
- dsl=0
- if [ ! -f $mycert ]; then
- dsl=0
- elif grep -i 'Proc-Type.*ENCRYPTED' "$mycert" > /dev/null 2>/dev/null; then
- dsl=1
- fi
- if [ "X$dsl" = "X1" ]; then
- echo ""
- echo "(** pausing $nsl secs for possible certificate passphrase dialog **)"
- echo ""
- sleep $nsl
- echo "(** done pausing for passphrase **)"
- echo ""
- fi
- fi
- #echo T sleep 1
- sleep 1
- rm -f "$tmp_cfg"
-fi
-
-
-echo ""
-if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
- echo "sleep $SSVNC_EXTRA_SLEEP"
- sleep $SSVNC_EXTRA_SLEEP
-fi
-if [ "X$SSVNC_EXTRA_COMMAND" != "X" ]; then
- (sh -c "$SSVNC_EXTRA_COMMAND") &
- echo "($SSVNC_EXTRA_COMMAND) &"; echo
-fi
-
-if [ "X$reverse" = "X" ]; then
- if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then
- port1=`expr 5900 + $N` # stunnel port
- port2=`findfree 5970` # bridge port (viewer connects to it.)
- N=`expr $port2 - 5900`
- env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="$port2,$port1" $ptmp &
- sleep 1
- fi
- echo "Running viewer:"
- vnc_hp=$localhost:$N
- if [ "X$stunnel_exec" != "X" ]; then
- vnc_hp="exec=$STUNNEL $tmp_cfg"
- fi
- echo "$VNCVIEWERCMD" "$@" "$vnc_hp"
- trap "final" 0 2 15
- echo ""
- $VNCVIEWERCMD "$@" "$vnc_hp"
- if [ $? != 0 ]; then
- echo "vncviewer command failed: $?"
- if [ "X$secondtry" = "X1" ]; then
- sleep 2
- $VNCVIEWERCMD "$@" "$vnc_hp"
- fi
- fi
-else
- echo "Running viewer:"
- echo ""
- echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
- echo ""
- trap "final" 0 2 15
- N2=$N
- N2_trim=`echo "$N2" | sed -e 's/://g'`
- if [ $N2_trim -le 200 ]; then
- N2_trim=`expr $N2_trim + 5500`
- fi
- if [ "X$proxy" != "X" ]; then
- if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
- pstunnel=`echo "$proxy" | awk -F: '{print $2}'`
- plisten=`echo "$proxy" | awk -F: '{print $3}'`
- IF=INADDR_ANY
- if [ "X$STUNNEL_LISTEN" != "X" ]; then
- IF=$STUNNEL_LISTEN
- fi
- PPROXY_VENCRYPT_REVERSE=1; export PPROXY_VENCRYPT_REVERSE
- PPROXY_LISTEN="$IF:$plisten"; export PPROXY_LISTEN
- PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY
- PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST
- STUNNEL_ONCE=1; export STUNNEL_ONCE
- STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
- if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then
- port1=`expr 5500 + $N2`
- port2=`findfree 5580`
- N2=`expr $port2 - 5500`
- N2_trim=`echo "$N2" | sed -e 's/://g'`
- if [ $N2_trim -le 200 ]; then
- N2_trim=`expr $N2_trim + 5500`
- fi
- if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
- PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself1.${RANDOM}.$$"`
- export PPROXY_LOOP_THYSELF
- PPROXY_LOOP_THYSELF0=$PPROXY_LOOP_THYSELF
- fi
- env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp &
- sleep 1
- fi
- else
- PPROXY_REVERSE="$localhost:$port"; export PPROXY_REVERSE
- PPROXY_SLEEP=1; export PPROXY_SLEEP;
- fi
- PPROXY_KILLPID=+1; export PPROXY_KILLPID;
- if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then
- PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself2.${RANDOM}.$$"`
- export PPROXY_LOOP_THYSELF
- fi
- $ptmp &
- # Important to have no extra pids generated between here and VNCVIEWERCMD
- fi
- if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
- N2=$N2_trim
- fi
- echo "$VNCVIEWERCMD" "$@" -listen $N2
- echo ""
- $VNCVIEWERCMD "$@" -listen $N2
-
- if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then
- rm -f $PPROXY_LOOP_THYSELF
- fi
- if [ "X$PPROXY_LOOP_THYSELF0" != "X" ]; then
- rm -f $PPROXY_LOOP_THYSELF0
- fi
-fi
-
-sleep 1
diff --git a/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch b/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch
deleted file mode 100644
index bc10f3c..0000000
--- a/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch
+++ /dev/null
@@ -1,111 +0,0 @@
---- vnc_javasrc.orig/VncCanvas.java 2004-10-10 02:15:54.000000000 -0400
-+++ vnc_javasrc/VncCanvas.java 2010-11-30 21:01:15.000000000 -0500
-@@ -28,13 +28,14 @@
- import java.lang.*;
- import java.util.zip.*;
-
-+import java.util.Collections;
-
- //
- // VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
- //
-
- class VncCanvas extends Canvas
-- implements KeyListener, MouseListener, MouseMotionListener {
-+ implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {
-
- VncViewer viewer;
- RfbProto rfb;
-@@ -81,6 +82,20 @@
- cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
- cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
-
-+ // kludge to not show any Java cursor in the canvas since we are
-+ // showing the soft cursor (should be a user setting...)
-+ Cursor dot = Toolkit.getDefaultToolkit().createCustomCursor(
-+ Toolkit.getDefaultToolkit().createImage(new byte[4]), new Point(0,0),
-+ "dot");
-+ this.setCursor(dot);
-+
-+ // while we are at it... get rid of the keyboard traversals that
-+ // make it so we can't type a Tab character:
-+ this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
-+ Collections.EMPTY_SET);
-+ this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
-+ Collections.EMPTY_SET);
-+
- colors = new Color[256];
- for (int i = 0; i < 256; i++)
- colors[i] = new Color(cm8.getRGB(i));
-@@ -169,6 +184,7 @@
- inputEnabled = true;
- addMouseListener(this);
- addMouseMotionListener(this);
-+ addMouseWheelListener(this);
- if (viewer.showControls) {
- viewer.buttonPanel.enableRemoteAccessControls(true);
- }
-@@ -177,6 +193,7 @@
- inputEnabled = false;
- removeMouseListener(this);
- removeMouseMotionListener(this);
-+ removeMouseWheelListener(this);
- if (viewer.showControls) {
- viewer.buttonPanel.enableRemoteAccessControls(false);
- }
-@@ -1190,6 +1207,9 @@
- public void mouseDragged(MouseEvent evt) {
- processLocalMouseEvent(evt, true);
- }
-+ public void mouseWheelMoved(MouseWheelEvent evt) {
-+ processLocalMouseWheelEvent(evt);
-+ }
-
- public void processLocalKeyEvent(KeyEvent evt) {
- if (viewer.rfb != null && rfb.inNormalProtocol) {
-@@ -1221,6 +1241,19 @@
- evt.consume();
- }
-
-+ public void processLocalMouseWheelEvent(MouseWheelEvent evt) {
-+ if (viewer.rfb != null && rfb.inNormalProtocol) {
-+ synchronized(rfb) {
-+ try {
-+ rfb.writeWheelEvent(evt);
-+ } catch (Exception e) {
-+ e.printStackTrace();
-+ }
-+ rfb.notify();
-+ }
-+ }
-+ }
-+
- public void processLocalMouseEvent(MouseEvent evt, boolean moved) {
- if (viewer.rfb != null && rfb.inNormalProtocol) {
- if (moved) {
-@@ -1387,9 +1420,9 @@
- result = cm8.getRGB(pixBuf[i]);
- } else {
- result = 0xFF000000 |
-- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
-- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
-- (pixBuf[i * 4 + 3] & 0xFF);
-+ (pixBuf[i * 4 + 2] & 0xFF) << 16 |
-+ (pixBuf[i * 4 + 1] & 0xFF) << 8 |
-+ (pixBuf[i * 4 + 0] & 0xFF);
- }
- } else {
- result = 0; // Transparent pixel
-@@ -1403,9 +1436,9 @@
- result = cm8.getRGB(pixBuf[i]);
- } else {
- result = 0xFF000000 |
-- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
-- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
-- (pixBuf[i * 4 + 3] & 0xFF);
-+ (pixBuf[i * 4 + 2] & 0xFF) << 16 |
-+ (pixBuf[i * 4 + 1] & 0xFF) << 8 |
-+ (pixBuf[i * 4 + 0] & 0xFF);
- }
- } else {
- result = 0; // Transparent pixel
diff --git a/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch b/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch
deleted file mode 100644
index 801234a..0000000
--- a/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch
+++ /dev/null
@@ -1,2600 +0,0 @@
-diff -Naur vnc_javasrc.orig/Makefile vnc_javasrc/Makefile
---- vnc_javasrc.orig/Makefile 2004-03-04 08:34:25.000000000 -0500
-+++ vnc_javasrc/Makefile 2010-05-18 20:56:26.000000000 -0400
-@@ -4,6 +4,7 @@
-
- CP = cp
- JC = javac
-+JC_ARGS = -target 1.4 -source 1.4
- JAR = jar
- ARCHIVE = VncViewer.jar
- MANIFEST = MANIFEST.MF
-@@ -15,25 +16,29 @@
- DesCipher.class CapabilityInfo.class CapsContainer.class \
- RecordingFrame.class SessionRecorder.class AuthUnixLoginPanel.class \
- SocketFactory.class HTTPConnectSocketFactory.class \
-- HTTPConnectSocket.class ReloginPanel.class
-+ HTTPConnectSocket.class ReloginPanel.class \
-+ SSLSocketToMe.class
-+
-+SSL_CLASSES = SSLSocketToMe*.class TrustDialog.class
-
- SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \
- OptionsFrame.java ClipboardFrame.java ButtonPanel.java \
- DesCipher.java CapabilityInfo.java CapsContainer.java \
- RecordingFrame.java SessionRecorder.java AuthUnixLoginPanel.java \
- SocketFactory.java HTTPConnectSocketFactory.java \
-- HTTPConnectSocket.java ReloginPanel.java
-+ HTTPConnectSocket.java ReloginPanel.java \
-+ SSLSocketToMe.java
-
- all: $(CLASSES) $(ARCHIVE)
-
- $(CLASSES): $(SOURCES)
-- $(JC) -target 1.1 -O $(SOURCES)
-+ $(JC) $(JC_ARGS) -O $(SOURCES)
-
- $(ARCHIVE): $(CLASSES) $(MANIFEST)
-- $(JAR) cfm $(ARCHIVE) $(MANIFEST) $(CLASSES)
-+ $(JAR) cfm $(ARCHIVE) $(MANIFEST) $(CLASSES) $(SSL_CLASSES)
-
- install: $(CLASSES) $(ARCHIVE)
-- $(CP) $(CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR)
-+ $(CP) $(CLASSES) $(SSL_CLASSES) $(ARCHIVE) $(PAGES) $(INSTALL_DIR)
-
- export:: $(CLASSES) $(ARCHIVE) $(PAGES)
- @$(ExportJavaClasses)
-diff -Naur vnc_javasrc.orig/RfbProto.java vnc_javasrc/RfbProto.java
---- vnc_javasrc.orig/RfbProto.java 2004-03-04 08:34:25.000000000 -0500
-+++ vnc_javasrc/RfbProto.java 2010-11-30 22:05:12.000000000 -0500
-@@ -199,7 +199,21 @@
- host = h;
- port = p;
-
-- if (viewer.socketFactory == null) {
-+ if (! viewer.disableSSL) {
-+ System.out.println("new SSLSocketToMe");
-+ SSLSocketToMe ssl;
-+ try {
-+ ssl = new SSLSocketToMe(host, port, v);
-+ } catch (Exception e) {
-+ throw new IOException(e.getMessage());
-+ }
-+
-+ try {
-+ sock = ssl.connectSock();
-+ } catch (Exception es) {
-+ throw new IOException(es.getMessage());
-+ }
-+ } else if (viewer.socketFactory == null) {
- sock = new Socket(host, port);
- } else {
- try {
-@@ -255,7 +269,7 @@
- || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n'))
- {
- throw new Exception("Host " + host + " port " + port +
-- " is not an RFB server");
-+ " is not an RFB server: " + b);
- }
-
- serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
-@@ -892,6 +906,38 @@
- final static int ALT_MASK = InputEvent.ALT_MASK;
-
-
-+ void writeWheelEvent(MouseWheelEvent evt) throws IOException {
-+
-+ eventBufLen = 0;
-+
-+ int x = evt.getX();
-+ int y = evt.getY();
-+
-+ if (x < 0) x = 0;
-+ if (y < 0) y = 0;
-+
-+ int ptrmask;
-+
-+ int clicks = evt.getWheelRotation();
-+ System.out.println("writeWheelEvent: clicks: " + clicks);
-+ if (clicks > 0) {
-+ ptrmask = 16;
-+ } else if (clicks < 0) {
-+ ptrmask = 8;
-+ } else {
-+ return;
-+ }
-+
-+ eventBuf[eventBufLen++] = (byte) PointerEvent;
-+ eventBuf[eventBufLen++] = (byte) ptrmask;
-+ eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff);
-+ eventBuf[eventBufLen++] = (byte) (x & 0xff);
-+ eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff);
-+ eventBuf[eventBufLen++] = (byte) (y & 0xff);
-+
-+ os.write(eventBuf, 0, eventBufLen);
-+ }
-+
- //
- // Write a pointer event message. We may need to send modifier key events
- // around it to set the correct modifier state.
-@@ -992,6 +1038,19 @@
- boolean down = (evt.getID() == KeyEvent.KEY_PRESSED);
-
- int key;
-+ if (viewer.debugKeyboard) {
-+ System.out.println("----------------------------------------");
-+ System.out.println("evt.getKeyChar: " + evt.getKeyChar());
-+ System.out.println("getKeyText: " + KeyEvent.getKeyText(evt.getKeyCode()));
-+ System.out.println("evt.getKeyCode: " + evt.getKeyCode());
-+ System.out.println("evt.getID: " + evt.getID());
-+ System.out.println("evt.getKeyLocation: " + evt.getKeyLocation());
-+ System.out.println("evt.isActionKey: " + evt.isActionKey());
-+ System.out.println("evt.isControlDown: " + evt.isControlDown());
-+ System.out.println("evt.getModifiers: " + evt.getModifiers());
-+ System.out.println("getKeyModifiersText: " + KeyEvent.getKeyModifiersText(evt.getModifiers()));
-+ System.out.println("evt.paramString: " + evt.paramString());
-+ }
- if (evt.isActionKey()) {
-
- //
-@@ -1025,6 +1084,13 @@
- return;
- }
-
-+ if(key == 0xffc2 && viewer.mapF5_to_atsign) {
-+ if (viewer.debugKeyboard) {
-+ System.out.println("Mapping: F5 -> AT ");
-+ }
-+ key = 0x40;
-+ }
-+
- } else {
-
- //
-@@ -1036,6 +1102,7 @@
-
- key = keyChar;
-
-+
- if (key < 0x20) {
- if (evt.isControlDown()) {
- key += 0x60;
-@@ -1121,6 +1188,16 @@
- int oldModifiers = 0;
-
- void writeModifierKeyEvents(int newModifiers) {
-+ if(viewer.forbid_Ctrl_Alt) {
-+ if ((newModifiers & CTRL_MASK) != 0 && (newModifiers & ALT_MASK) != 0) {
-+ int orig = newModifiers;
-+ newModifiers &= ~ALT_MASK;
-+ newModifiers &= ~CTRL_MASK;
-+ if (viewer.debugKeyboard) {
-+ System.out.println("Ctrl+Alt modifiers: " + orig + " -> " + newModifiers);
-+ }
-+ }
-+ }
- if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK))
- writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0);
-
-diff -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSLSocketToMe.java
---- vnc_javasrc.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500
-+++ vnc_javasrc/SSLSocketToMe.java 2010-07-10 19:18:06.000000000 -0400
-@@ -0,0 +1,2067 @@
-+/*
-+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
-+ *
-+ * Copyright (c) 2006 Karl J. Runge <runge@karlrunge.com>
-+ * All rights reserved.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ *
-+ */
-+
-+import java.net.*;
-+import java.io.*;
-+import javax.net.ssl.*;
-+import java.util.*;
-+
-+import java.security.*;
-+import java.security.cert.*;
-+import java.security.spec.*;
-+import java.security.cert.Certificate;
-+import java.security.cert.CertificateFactory;
-+
-+import java.awt.*;
-+import java.awt.event.*;
-+
-+public class SSLSocketToMe {
-+
-+ /* basic member data: */
-+ String host;
-+ int port;
-+ VncViewer viewer;
-+
-+ boolean debug = true;
-+ boolean debug_certs = false;
-+
-+ /* sockets */
-+ SSLSocket socket = null;
-+ SSLSocketFactory factory;
-+
-+ /* fallback for Proxy connection */
-+ boolean proxy_in_use = false;
-+ boolean proxy_failure = false;
-+ public DataInputStream is = null;
-+ public OutputStream os = null;
-+
-+ /* strings from user WRT proxy: */
-+ String proxy_auth_string = null;
-+ String proxy_dialog_host = null;
-+ int proxy_dialog_port = 0;
-+
-+ Socket proxySock;
-+ DataInputStream proxy_is;
-+ OutputStream proxy_os;
-+
-+ /* trust contexts */
-+ SSLContext trustloc_ctx;
-+ SSLContext trustall_ctx;
-+ SSLContext trustsrv_ctx;
-+ SSLContext trusturl_ctx;
-+ SSLContext trustone_ctx;
-+
-+ /* corresponding trust managers */
-+ TrustManager[] trustAllCerts;
-+ TrustManager[] trustSrvCert;
-+ TrustManager[] trustUrlCert;
-+ TrustManager[] trustOneCert;
-+
-+ /* client-side SSL auth key (oneTimeKey=...) */
-+ KeyManager[] mykey = null;
-+
-+ boolean user_wants_to_see_cert = true;
-+ String cert_fail = null;
-+
-+ /* cert(s) we retrieve from Web server, VNC server, or serverCert param: */
-+ java.security.cert.Certificate[] trustallCerts = null;
-+ java.security.cert.Certificate[] trustsrvCerts = null;
-+ java.security.cert.Certificate[] trusturlCerts = null;
-+
-+ /* utility to decode hex oneTimeKey=... and serverCert=... */
-+ byte[] hex2bytes(String s) {
-+ byte[] bytes = new byte[s.length()/2];
-+ for (int i=0; i<s.length()/2; i++) {
-+ int j = 2*i;
-+ try {
-+ int val = Integer.parseInt(s.substring(j, j+2), 16);
-+ if (val > 127) {
-+ val -= 256;
-+ }
-+ Integer I = new Integer(val);
-+ bytes[i] = Byte.decode(I.toString()).byteValue();
-+
-+ } catch (Exception e) {
-+ ;
-+ }
-+ }
-+ return bytes;
-+ }
-+
-+ SSLSocketToMe(String h, int p, VncViewer v) throws Exception {
-+ host = h;
-+ port = p;
-+ viewer = v;
-+
-+ debug_certs = v.debugCerts;
-+
-+ /* we will first try default factory for certification: */
-+
-+ factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
-+
-+ dbg("SSL startup: " + host + " " + port);
-+
-+
-+ /* create trust managers to be used if initial handshake fails: */
-+
-+ trustAllCerts = new TrustManager[] {
-+ /*
-+ * this one accepts everything. Only used if user
-+ * has disabled checking (trustAllVncCerts=yes)
-+ * or when we grab the cert to show it to them in
-+ * a dialog and ask them to manually verify/accept it.
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) {
-+ /* empty */
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) {
-+ /* empty */
-+ dbg("ALL: an untrusted connect to grab cert.");
-+ }
-+ }
-+ };
-+
-+ trustUrlCert = new TrustManager[] {
-+ /*
-+ * this one accepts only the retrieved server
-+ * cert by SSLSocket by this applet and stored in
-+ * trusturlCerts.
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ throw new CertificateException("No Clients (URL)");
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ /* we want to check 'certs' against 'trusturlCerts' */
-+ if (trusturlCerts == null) {
-+ throw new CertificateException(
-+ "No Trust url Certs array.");
-+ }
-+ if (trusturlCerts.length < 1) {
-+ throw new CertificateException(
-+ "No Trust url Certs.");
-+ }
-+ if (certs == null) {
-+ throw new CertificateException(
-+ "No this-certs array.");
-+ }
-+ if (certs.length < 1) {
-+ throw new CertificateException(
-+ "No this-certs Certs.");
-+ }
-+ if (certs.length != trusturlCerts.length) {
-+ throw new CertificateException(
-+ "certs.length != trusturlCerts.length " + certs.length + " " + trusturlCerts.length);
-+ }
-+ boolean ok = true;
-+ for (int i = 0; i < certs.length; i++) {
-+ if (! trusturlCerts[i].equals(certs[i])) {
-+ ok = false;
-+ dbg("URL: cert mismatch at i=" + i);
-+ dbg("URL: cert mismatch cert" + certs[i]);
-+ dbg("URL: cert mismatch url" + trusturlCerts[i]);
-+ if (cert_fail == null) {
-+ cert_fail = "cert-mismatch";
-+ }
-+ }
-+ if (debug_certs) {
-+ dbg("\n***********************************************");
-+ dbg("URL: cert info at i=" + i);
-+ dbg("URL: cert info cert" + certs[i]);
-+ dbg("===============================================");
-+ dbg("URL: cert info url" + trusturlCerts[i]);
-+ dbg("***********************************************");
-+ }
-+ }
-+ if (!ok) {
-+ throw new CertificateException(
-+ "Server Cert Chain != URL Cert Chain.");
-+ }
-+ dbg("URL: trusturlCerts[i] matches certs[i] i=0:" + (certs.length-1));
-+ }
-+ }
-+ };
-+
-+ trustSrvCert = new TrustManager[] {
-+ /*
-+ * this one accepts cert given to us in the serverCert
-+ * Applet Parameter we were started with. It is
-+ * currently a fatal error if the VNC Server's cert
-+ * doesn't match it.
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ throw new CertificateException("No Clients (SRV)");
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ /* we want to check 'certs' against 'trustsrvCerts' */
-+ if (trustsrvCerts == null) {
-+ throw new CertificateException(
-+ "No Trust srv Certs array.");
-+ }
-+ if (trustsrvCerts.length < 1) {
-+ throw new CertificateException(
-+ "No Trust srv Certs.");
-+ }
-+ if (certs == null) {
-+ throw new CertificateException(
-+ "No this-certs array.");
-+ }
-+ if (certs.length < 1) {
-+ throw new CertificateException(
-+ "No this-certs Certs.");
-+ }
-+ if (certs.length != trustsrvCerts.length) {
-+ throw new CertificateException(
-+ "certs.length != trustsrvCerts.length " + certs.length + " " + trustsrvCerts.length);
-+ }
-+ boolean ok = true;
-+ for (int i = 0; i < certs.length; i++) {
-+ if (! trustsrvCerts[i].equals(certs[i])) {
-+ ok = false;
-+ dbg("SRV: cert mismatch at i=" + i);
-+ dbg("SRV: cert mismatch cert" + certs[i]);
-+ dbg("SRV: cert mismatch srv" + trustsrvCerts[i]);
-+ if (cert_fail == null) {
-+ cert_fail = "server-cert-mismatch";
-+ }
-+ }
-+ if (debug_certs) {
-+ dbg("\n***********************************************");
-+ dbg("SRV: cert info at i=" + i);
-+ dbg("SRV: cert info cert" + certs[i]);
-+ dbg("===============================================");
-+ dbg("SRV: cert info srv" + trustsrvCerts[i]);
-+ dbg("***********************************************");
-+ }
-+ }
-+ if (!ok) {
-+ throw new CertificateException(
-+ "Server Cert Chain != serverCert Applet Parameter Cert Chain.");
-+ }
-+ dbg("SRV: trustsrvCerts[i] matches certs[i] i=0:" + (certs.length-1));
-+ }
-+ }
-+ };
-+
-+ trustOneCert = new TrustManager[] {
-+ /*
-+ * this one accepts only the retrieved server
-+ * cert by SSLSocket by this applet we stored in
-+ * trustallCerts that user has accepted or applet
-+ * parameter trustAllVncCerts=yes is set. This is
-+ * for when we reconnect after the user has manually
-+ * accepted the trustall cert in the dialog (or set
-+ * trustAllVncCerts=yes applet param.)
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ throw new CertificateException("No Clients (ONE)");
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ /* we want to check 'certs' against 'trustallCerts' */
-+ if (trustallCerts == null) {
-+ throw new CertificateException(
-+ "No Trust All Server Certs array.");
-+ }
-+ if (trustallCerts.length < 1) {
-+ throw new CertificateException(
-+ "No Trust All Server Certs.");
-+ }
-+ if (certs == null) {
-+ throw new CertificateException(
-+ "No this-certs array.");
-+ }
-+ if (certs.length < 1) {
-+ throw new CertificateException(
-+ "No this-certs Certs.");
-+ }
-+ if (certs.length != trustallCerts.length) {
-+ throw new CertificateException(
-+ "certs.length != trustallCerts.length " + certs.length + " " + trustallCerts.length);
-+ }
-+ boolean ok = true;
-+ for (int i = 0; i < certs.length; i++) {
-+ if (! trustallCerts[i].equals(certs[i])) {
-+ ok = false;
-+ dbg("ONE: cert mismatch at i=" + i);
-+ dbg("ONE: cert mismatch cert" + certs[i]);
-+ dbg("ONE: cert mismatch all" + trustallCerts[i]);
-+ }
-+ if (debug_certs) {
-+ dbg("\n***********************************************");
-+ dbg("ONE: cert info at i=" + i);
-+ dbg("ONE: cert info cert" + certs[i]);
-+ dbg("===============================================");
-+ dbg("ONE: cert info all" + trustallCerts[i]);
-+ dbg("***********************************************");
-+ }
-+ }
-+ if (!ok) {
-+ throw new CertificateException(
-+ "Server Cert Chain != TRUSTALL Cert Chain.");
-+ }
-+ dbg("ONE: trustallCerts[i] matches certs[i] i=0:" + (certs.length-1));
-+ }
-+ }
-+ };
-+
-+ /*
-+ * The above TrustManagers are used:
-+ *
-+ * 1) to retrieve the server cert in case of failure to
-+ * display it to the user in a dialog.
-+ * 2) to subsequently connect to the server if user agrees.
-+ */
-+
-+ /*
-+ * build oneTimeKey cert+key if supplied in applet parameter:
-+ */
-+ if (viewer.oneTimeKey != null && viewer.oneTimeKey.equals("PROMPT")) {
-+ ClientCertDialog d = new ClientCertDialog();
-+ viewer.oneTimeKey = d.queryUser();
-+ }
-+ if (viewer.oneTimeKey != null && viewer.oneTimeKey.indexOf(",") > 0) {
-+ int idx = viewer.oneTimeKey.indexOf(",");
-+
-+ String onetimekey = viewer.oneTimeKey.substring(0, idx);
-+ byte[] key = hex2bytes(onetimekey);
-+ String onetimecert = viewer.oneTimeKey.substring(idx+1);
-+ byte[] cert = hex2bytes(onetimecert);
-+
-+ KeyFactory kf = KeyFactory.getInstance("RSA");
-+ PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
-+ PrivateKey ff = kf.generatePrivate (keysp);
-+ if (debug_certs) {
-+ dbg("one time key " + ff);
-+ }
-+
-+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
-+ Collection c = cf.generateCertificates(new ByteArrayInputStream(cert));
-+ Certificate[] certs = new Certificate[c.toArray().length];
-+ if (c.size() == 1) {
-+ Certificate tmpcert = cf.generateCertificate(new ByteArrayInputStream(cert));
-+ if (debug_certs) {
-+ dbg("one time cert" + tmpcert);
-+ }
-+ certs[0] = tmpcert;
-+ } else {
-+ certs = (Certificate[]) c.toArray();
-+ }
-+
-+ KeyStore ks = KeyStore.getInstance("JKS");
-+ ks.load(null, null);
-+ ks.setKeyEntry("onetimekey", ff, "".toCharArray(), certs);
-+ String da = KeyManagerFactory.getDefaultAlgorithm();
-+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(da);
-+ kmf.init(ks, "".toCharArray());
-+
-+ mykey = kmf.getKeyManagers();
-+ }
-+
-+ /*
-+ * build serverCert cert if supplied in applet parameter:
-+ */
-+ if (viewer.serverCert != null) {
-+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
-+ byte[] cert = hex2bytes(viewer.serverCert);
-+ Collection c = cf.generateCertificates(new ByteArrayInputStream(cert));
-+ trustsrvCerts = new Certificate[c.toArray().length];
-+ if (c.size() == 1) {
-+ Certificate tmpcert = cf.generateCertificate(new ByteArrayInputStream(cert));
-+ trustsrvCerts[0] = tmpcert;
-+ } else {
-+ trustsrvCerts = (Certificate[]) c.toArray();
-+ }
-+ }
-+
-+ /* the trust loc certs context: */
-+ try {
-+ trustloc_ctx = SSLContext.getInstance("SSL");
-+
-+ /*
-+ * below is a failed attempt to get jvm's default
-+ * trust manager using null (below) makes it so
-+ * for HttpsURLConnection the server cannot be
-+ * verified (no prompting.)
-+ */
-+ if (false) {
-+ boolean didit = false;
-+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-+ tmf.init((KeyStore) null);
-+ TrustManager [] tml = tmf.getTrustManagers();
-+ for (int i = 0; i < tml.length; i++) {
-+ TrustManager tm = tml[i];
-+ if (tm instanceof X509TrustManager) {
-+ TrustManager tm1[] = new TrustManager[1];
-+ tm1[0] = tm;
-+ trustloc_ctx.init(mykey, tm1, null);
-+ didit = true;
-+ break;
-+ }
-+ }
-+ if (!didit) {
-+ trustloc_ctx.init(mykey, null, null);
-+ }
-+ } else {
-+ /* we have to set trust manager to null */
-+ trustloc_ctx.init(mykey, null, null);
-+ }
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustloc_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust all certs context: */
-+ try {
-+ trustall_ctx = SSLContext.getInstance("SSL");
-+ trustall_ctx.init(mykey, trustAllCerts, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustall_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust url certs context: */
-+ try {
-+ trusturl_ctx = SSLContext.getInstance("SSL");
-+ trusturl_ctx.init(mykey, trustUrlCert, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trusturl_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust srv certs context: */
-+ try {
-+ trustsrv_ctx = SSLContext.getInstance("SSL");
-+ trustsrv_ctx.init(mykey, trustSrvCert, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustsrv_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust the one cert from server context: */
-+ try {
-+ trustone_ctx = SSLContext.getInstance("SSL");
-+ trustone_ctx.init(mykey, trustOneCert, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustone_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+ }
-+
-+ /*
-+ * we call this early on to 1) check for a proxy, 2) grab
-+ * Browser/JVM accepted HTTPS cert.
-+ */
-+ public void check_for_proxy_and_grab_vnc_server_cert() {
-+
-+ trusturlCerts = null;
-+ proxy_in_use = false;
-+
-+ if (viewer.ignoreProxy) {
-+ /* applet param says skip it. */
-+ /* the downside is we do not set trusturlCerts for comparison later... */
-+ /* nor do we autodetect x11vnc for GET=1. */
-+ return;
-+ }
-+
-+ dbg("------------------------------------------------");
-+ dbg("Into check_for_proxy_and_grab_vnc_server_cert():");
-+
-+ dbg("TRYING HTTPS:");
-+ String ustr = "https://" + host + ":";
-+ if (viewer.httpsPort != null) {
-+ ustr += viewer.httpsPort;
-+ } else {
-+ ustr += port;
-+ }
-+ ustr += viewer.urlPrefix + "/check.https.proxy.connection";
-+ dbg("ustr is: " + ustr);
-+
-+ try {
-+ /* prepare for an HTTPS URL connection to host:port */
-+ URL url = new URL(ustr);
-+ HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
-+
-+ if (mykey != null) {
-+ /* with oneTimeKey (mykey) we can't use the default SSL context */
-+ if (trustsrvCerts != null) {
-+ dbg("passing trustsrv_ctx to HttpsURLConnection to provide client cert.");
-+ https.setSSLSocketFactory(trustsrv_ctx.getSocketFactory());
-+ } else if (trustloc_ctx != null) {
-+ dbg("passing trustloc_ctx to HttpsURLConnection to provide client cert.");
-+ https.setSSLSocketFactory(trustloc_ctx.getSocketFactory());
-+ }
-+ }
-+
-+ https.setUseCaches(false);
-+ https.setRequestMethod("GET");
-+ https.setRequestProperty("Pragma", "No-Cache");
-+ https.setRequestProperty("Proxy-Connection", "Keep-Alive");
-+ https.setDoInput(true);
-+
-+ dbg("trying https.connect()");
-+ https.connect();
-+
-+ dbg("trying https.getServerCertificates()");
-+ trusturlCerts = https.getServerCertificates();
-+
-+ if (trusturlCerts == null) {
-+ dbg("set trusturlCerts to null!");
-+ } else {
-+ dbg("set trusturlCerts to non-null");
-+ }
-+
-+ if (https.usingProxy()) {
-+ proxy_in_use = true;
-+ dbg("An HTTPS proxy is in use. There may be connection problems.");
-+ }
-+
-+ dbg("trying https.getContent()");
-+ Object output = https.getContent();
-+ dbg("trying https.disconnect()");
-+ https.disconnect();
-+ if (! viewer.GET) {
-+ String header = https.getHeaderField("VNC-Server");
-+ if (header != null && header.startsWith("x11vnc")) {
-+ dbg("detected x11vnc server (1), setting GET=1");
-+ viewer.GET = true;
-+ }
-+ }
-+
-+ } catch(Exception e) {
-+ dbg("HttpsURLConnection: " + e.getMessage());
-+ }
-+
-+ if (proxy_in_use) {
-+ dbg("exit check_for_proxy_and_grab_vnc_server_cert():");
-+ dbg("------------------------------------------------");
-+ return;
-+ } else if (trusturlCerts != null && !viewer.forceProxy) {
-+ /* Allow user to require HTTP check? use forceProxy for now. */
-+ dbg("SKIPPING HTTP PROXY CHECK: got trusturlCerts, assuming proxy info is correct.");
-+ dbg("exit check_for_proxy_and_grab_vnc_server_cert():");
-+ dbg("------------------------------------------------");
-+ return;
-+ }
-+
-+ /*
-+ * XXX need to remember scenario where this extra check
-+ * gives useful info. User's Browser proxy settings?
-+ */
-+ dbg("TRYING HTTP:");
-+ ustr = "http://" + host + ":" + port;
-+ ustr += viewer.urlPrefix + "/index.vnc";
-+ dbg("ustr is: " + ustr);
-+
-+ try {
-+ /* prepare for an HTTP URL connection to the same host:port (but not httpsPort) */
-+ URL url = new URL(ustr);
-+ HttpURLConnection http = (HttpURLConnection)
-+ url.openConnection();
-+
-+ http.setUseCaches(false);
-+ http.setRequestMethod("GET");
-+ http.setRequestProperty("Pragma", "No-Cache");
-+ http.setRequestProperty("Proxy-Connection", "Keep-Alive");
-+ http.setDoInput(true);
-+
-+ dbg("trying http.connect()");
-+ http.connect();
-+
-+ if (http.usingProxy()) {
-+ proxy_in_use = true;
-+ dbg("An HTTP proxy is in use. There may be connection problems.");
-+ }
-+ dbg("trying http.getContent()");
-+ Object output = http.getContent();
-+ dbg("trying http.disconnect()");
-+ http.disconnect();
-+ if (! viewer.GET) {
-+ String header = http.getHeaderField("VNC-Server");
-+ if (header != null && header.startsWith("x11vnc")) {
-+ dbg("detected x11vnc server (2), setting GET=1");
-+ viewer.GET = true;
-+ }
-+ }
-+ } catch(Exception e) {
-+ dbg("HttpURLConnection: " + e.getMessage());
-+ }
-+ dbg("exit check_for_proxy_and_grab_vnc_server_cert():");
-+ dbg("------------------------------------------------");
-+ }
-+
-+ public Socket connectSock() throws IOException {
-+ /*
-+ * first try a https connection to detect a proxy, and
-+ * grab the VNC server cert at the same time:
-+ */
-+ check_for_proxy_and_grab_vnc_server_cert();
-+
-+ boolean srv_cert = false;
-+
-+ if (trustsrvCerts != null) {
-+ /* applet parameter suppled serverCert */
-+ dbg("viewer.trustSrvCert-0 using trustsrv_ctx");
-+ factory = trustsrv_ctx.getSocketFactory();
-+ srv_cert = true;
-+ } else if (viewer.trustAllVncCerts) {
-+ /* trust all certs (no checking) */
-+ dbg("viewer.trustAllVncCerts-0 using trustall_ctx");
-+ factory = trustall_ctx.getSocketFactory();
-+ } else if (trusturlCerts != null) {
-+ /* trust certs the Browser/JVM accepted in check_for_proxy... */
-+ dbg("using trusturl_ctx");
-+ factory = trusturl_ctx.getSocketFactory();
-+ } else {
-+ /* trust the local defaults */
-+ dbg("using trustloc_ctx");
-+ factory = trustloc_ctx.getSocketFactory();
-+ }
-+
-+ socket = null;
-+
-+ try {
-+ if (proxy_in_use && viewer.forceProxy) {
-+ throw new Exception("forcing proxy (forceProxy)");
-+ } else if (viewer.CONNECT != null) {
-+ throw new Exception("forcing CONNECT");
-+ }
-+
-+ int timeout = 6;
-+ if (timeout > 0) {
-+ socket = (SSLSocket) factory.createSocket();
-+ InetSocketAddress inetaddr = new InetSocketAddress(host, port);
-+ dbg("Using timeout of " + timeout + " secs to: " + host + ":" + port);
-+ socket.connect(inetaddr, timeout * 1000);
-+ } else {
-+ socket = (SSLSocket) factory.createSocket(host, port);
-+ }
-+
-+ } catch (Exception esock) {
-+ dbg("socket error: " + esock.getMessage());
-+ if (proxy_in_use || viewer.CONNECT != null) {
-+ proxy_failure = true;
-+ if (proxy_in_use) {
-+ dbg("HTTPS proxy in use. Trying to go with it.");
-+ } else {
-+ dbg("viewer.CONNECT reverse proxy in use. Trying to go with it.");
-+ }
-+ try {
-+ socket = proxy_socket(factory);
-+ } catch (Exception e) {
-+ dbg("proxy_socket error: " + e.getMessage());
-+ }
-+ } else {
-+ /* n.b. socket is left in error state to cause ex. below. */
-+ }
-+ }
-+
-+ try {
-+ socket.startHandshake();
-+
-+ dbg("The Server Connection Verified OK on 1st try.");
-+
-+ java.security.cert.Certificate[] currentTrustedCerts;
-+ BrowserCertsDialog bcd;
-+
-+ SSLSession sess = socket.getSession();
-+ currentTrustedCerts = sess.getPeerCertificates();
-+
-+ if (viewer.trustAllVncCerts) {
-+ dbg("viewer.trustAllVncCerts-1 keeping socket.");
-+ } else if (currentTrustedCerts == null || currentTrustedCerts.length < 1) {
-+ try {
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy.");
-+ }
-+ socket = null;
-+ throw new SSLHandshakeException("no current certs");
-+ }
-+
-+ String serv = "";
-+ try {
-+ CertInfo ci = new CertInfo(currentTrustedCerts[0]);
-+ serv = ci.get_certinfo("CN");
-+ } catch (Exception e) {
-+ ;
-+ }
-+
-+ if (viewer.trustAllVncCerts) {
-+ dbg("viewer.trustAllVncCerts-2 skipping browser certs dialog");
-+ user_wants_to_see_cert = false;
-+ } else if (viewer.serverCert != null && trustsrvCerts != null) {
-+ dbg("viewer.serverCert-1 skipping browser certs dialog");
-+ user_wants_to_see_cert = false;
-+ } else if (viewer.trustUrlVncCert) {
-+ dbg("viewer.trustUrlVncCert-1 skipping browser certs dialog");
-+ user_wants_to_see_cert = false;
-+ } else {
-+ /* have a dialog with the user: */
-+ bcd = new BrowserCertsDialog(serv, host + ":" + port);
-+ dbg("browser certs dialog begin.");
-+ bcd.queryUser();
-+ dbg("browser certs dialog finished.");
-+
-+ if (bcd.showCertDialog) {
-+ String msg = "user wants to see cert";
-+ dbg(msg);
-+ user_wants_to_see_cert = true;
-+ if (cert_fail == null) {
-+ cert_fail = "user-view";
-+ }
-+ throw new SSLHandshakeException(msg);
-+ } else {
-+ user_wants_to_see_cert = false;
-+ dbg("browser certs dialog: user said yes, accept it");
-+ }
-+ }
-+
-+ } catch (SSLHandshakeException eh) {
-+ dbg("SSLHandshakeException: could not automatically verify Server.");
-+ dbg("msg: " + eh.getMessage());
-+
-+
-+ /* send a cleanup string just in case: */
-+ String getoutstr = "GET /index.vnc HTTP/1.0\r\nConnection: close\r\n\r\n";
-+
-+ try {
-+ OutputStream os = socket.getOutputStream();
-+ os.write(getoutstr.getBytes());
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy!");
-+ }
-+
-+ /* reload */
-+
-+ socket = null;
-+
-+ String reason = null;
-+
-+ if (srv_cert) {
-+ /* for serverCert usage we make this a fatal error. */
-+ throw new IOException("Fatal: VNC Server's Cert does not match Applet Parameter 'serverCert=...'");
-+ /* see below in TrustDialog were we describe this case to user anyway */
-+ }
-+
-+ /*
-+ * Reconnect, trusting any cert, so we can grab
-+ * the cert to show it to the user in a dialog
-+ * for him to manually accept. This connection
-+ * is not used for anything else.
-+ */
-+ factory = trustall_ctx.getSocketFactory();
-+ if (proxy_failure) {
-+ socket = proxy_socket(factory);
-+ } else {
-+ socket = (SSLSocket) factory.createSocket(host, port);
-+ }
-+
-+ if (debug_certs) {
-+ dbg("trusturlCerts: " + trusturlCerts);
-+ dbg("trustsrvCerts: " + trustsrvCerts);
-+ }
-+ if (trusturlCerts == null && cert_fail == null) {
-+ cert_fail = "missing-certs";
-+ }
-+
-+ try {
-+ socket.startHandshake();
-+
-+ dbg("The TrustAll Server Cert-grab Connection (trivially) Verified OK.");
-+
-+ /* grab the cert: */
-+ try {
-+ SSLSession sess = socket.getSession();
-+ trustallCerts = sess.getPeerCertificates();
-+ } catch (Exception e) {
-+ throw new Exception("Could not get " +
-+ "Peer Certificate");
-+ }
-+ if (debug_certs) {
-+ dbg("trustallCerts: " + trustallCerts);
-+ }
-+
-+ if (viewer.trustAllVncCerts) {
-+ dbg("viewer.trustAllVncCerts-3. skipping dialog, trusting everything.");
-+ } else if (! browser_cert_match()) {
-+ /*
-+ * close socket now, we will reopen after
-+ * dialog if user agrees to use the cert.
-+ */
-+ try {
-+ OutputStream os = socket.getOutputStream();
-+ os.write(getoutstr.getBytes());
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy!!");
-+ }
-+ socket = null;
-+
-+ /* dialog with user to accept cert or not: */
-+
-+ TrustDialog td= new TrustDialog(host, port,
-+ trustallCerts);
-+
-+ if (cert_fail == null) {
-+ ;
-+ } else if (cert_fail.equals("user-view")) {
-+ reason = "Reason for this Dialog:\n\n"
-+ + " You Asked to View the Certificate.";
-+ } else if (cert_fail.equals("server-cert-mismatch")) {
-+ /* this is now fatal error, see above. */
-+ reason = "Reason for this Dialog:\n\n"
-+ + " The VNC Server's Certificate does not match the Certificate\n"
-+ + " specified in the supplied 'serverCert' Applet Parameter.";
-+ } else if (cert_fail.equals("cert-mismatch")) {
-+ reason = "Reason for this Dialog:\n\n"
-+ + " The VNC Server's Certificate does not match the Website's\n"
-+ + " HTTPS Certificate (that you previously accepted; either\n"
-+ + " manually or automatically via Certificate Authority.)";
-+ } else if (cert_fail.equals("missing-certs")) {
-+ reason = "Reason for this Dialog:\n\n"
-+ + " Not all Certificates could be obtained to check.";
-+ }
-+
-+ if (! td.queryUser(reason)) {
-+ String msg = "User decided against it.";
-+ dbg(msg);
-+ throw new IOException(msg);
-+ }
-+ }
-+
-+ } catch (Exception ehand2) {
-+ dbg("** Could not TrustAll Verify Server!");
-+
-+ throw new IOException(ehand2.getMessage());
-+ }
-+
-+ /* reload again: */
-+
-+ if (socket != null) {
-+ try {
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy!!!");
-+ }
-+ socket = null;
-+ }
-+
-+ /*
-+ * Now connect a 3rd time, using the cert
-+ * retrieved during connection 2 (sadly, that
-+ * the user likely blindly agreed to...)
-+ */
-+
-+ factory = trustone_ctx.getSocketFactory();
-+ if (proxy_failure) {
-+ socket = proxy_socket(factory);
-+ } else {
-+ socket = (SSLSocket) factory.createSocket(host, port);
-+ }
-+
-+ try {
-+ socket.startHandshake();
-+ dbg("TrustAll/TrustOne Server Connection Verified #3.");
-+
-+ } catch (Exception ehand3) {
-+ dbg("** Could not TrustAll/TrustOne Verify Server #3.");
-+
-+ throw new IOException(ehand3.getMessage());
-+ }
-+ }
-+
-+ /* we have socket (possibly null) at this point, so proceed: */
-+
-+ /* handle x11vnc GET=1, if applicable: */
-+ if (socket != null && viewer.GET) {
-+ String str = "GET ";
-+ str += viewer.urlPrefix;
-+ str += "/request.https.vnc.connection";
-+ str += " HTTP/1.0\r\n";
-+ str += "Pragma: No-Cache\r\n";
-+ str += "\r\n";
-+
-+ System.out.println("sending: " + str);
-+ OutputStream os = socket.getOutputStream();
-+ String type = "os";
-+
-+ if (type == "os") {
-+ os.write(str.getBytes());
-+ os.flush();
-+ System.out.println("used OutputStream");
-+ } else if (type == "bs") {
-+ BufferedOutputStream bs = new BufferedOutputStream(os);
-+ bs.write(str.getBytes());
-+ bs.flush();
-+ System.out.println("used BufferedOutputStream");
-+ } else if (type == "ds") {
-+ DataOutputStream ds = new DataOutputStream(os);
-+ ds.write(str.getBytes());
-+ ds.flush();
-+ System.out.println("used DataOutputStream");
-+ }
-+ if (false) {
-+ String rep = "";
-+ DataInputStream is = new DataInputStream(
-+ new BufferedInputStream(socket.getInputStream(), 16384));
-+ while (true) {
-+ rep += readline(is);
-+ if (rep.indexOf("\r\n\r\n") >= 0) {
-+ break;
-+ }
-+ }
-+ System.out.println("rep: " + rep);
-+ }
-+ }
-+
-+ dbg("SSL returning socket to caller.");
-+ dbg("");
-+
-+ /* could be null, let caller handle that. */
-+ return (Socket) socket;
-+ }
-+
-+ boolean browser_cert_match() {
-+ String msg = "Browser URL accept previously accepted cert";
-+
-+ if (user_wants_to_see_cert) {
-+ return false;
-+ }
-+
-+ if (viewer.serverCert != null || trustsrvCerts != null) {
-+ if (cert_fail == null) {
-+ cert_fail = "server-cert-mismatch";
-+ }
-+ }
-+ if (trustallCerts != null && trusturlCerts != null) {
-+ if (trustallCerts.length == trusturlCerts.length) {
-+ boolean ok = true;
-+ /* check toath trustallCerts (socket) equals trusturlCerts (browser) */
-+ for (int i = 0; i < trusturlCerts.length; i++) {
-+ if (! trustallCerts[i].equals(trusturlCerts[i])) {
-+ dbg("BCM: cert mismatch at i=" + i);
-+ dbg("BCM: cert mismatch url" + trusturlCerts[i]);
-+ dbg("BCM: cert mismatch all" + trustallCerts[i]);
-+ ok = false;
-+ }
-+ }
-+ if (ok) {
-+ System.out.println(msg);
-+ if (cert_fail == null) {
-+ cert_fail = "did-not-fail";
-+ }
-+ return true;
-+ } else {
-+ if (cert_fail == null) {
-+ cert_fail = "cert-mismatch";
-+ }
-+ return false;
-+ }
-+ }
-+ }
-+ if (cert_fail == null) {
-+ cert_fail = "missing-certs";
-+ }
-+ return false;
-+ }
-+
-+ private void dbg(String s) {
-+ if (debug) {
-+ System.out.println(s);
-+ }
-+ }
-+
-+ private int gint(String s) {
-+ int n = -1;
-+ try {
-+ Integer I = new Integer(s);
-+ n = I.intValue();
-+ } catch (Exception ex) {
-+ return -1;
-+ }
-+ return n;
-+ }
-+
-+ /* this will do the proxy CONNECT negotiation and hook us up. */
-+
-+ private void proxy_helper(String proxyHost, int proxyPort) {
-+
-+ boolean proxy_auth = false;
-+ String proxy_auth_basic_realm = "";
-+ String hp = host + ":" + port;
-+ dbg("proxy_helper: " + proxyHost + ":" + proxyPort + " hp: " + hp);
-+
-+ /* we loop here a few times trying for the password case */
-+ for (int k=0; k < 2; k++) {
-+ dbg("proxy_in_use psocket: " + k);
-+
-+ if (proxySock != null) {
-+ try {
-+ proxySock.close();
-+ } catch (Exception e) {
-+ dbg("proxy socket is grumpy.");
-+ }
-+ }
-+
-+ proxySock = psocket(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ dbg("1-a sadly, returning a null socket");
-+ return;
-+ }
-+
-+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
-+ + "Host: " + hp + "\r\n";
-+
-+ dbg("requesting via proxy: " + req1);
-+
-+ if (proxy_auth) {
-+ if (proxy_auth_string == null) {
-+ ProxyPasswdDialog pp = new ProxyPasswdDialog(proxyHost, proxyPort, proxy_auth_basic_realm);
-+ pp.queryUser();
-+ proxy_auth_string = pp.getAuth();
-+ }
-+ //dbg("auth1: " + proxy_auth_string);
-+
-+ String auth2 = Base64Coder.encodeString(proxy_auth_string);
-+ //dbg("auth2: " + auth2);
-+
-+ req1 += "Proxy-Authorization: Basic " + auth2 + "\r\n";
-+ //dbg("req1: " + req1);
-+
-+ dbg("added Proxy-Authorization: Basic ... to request");
-+ }
-+ req1 += "\r\n";
-+
-+ try {
-+ proxy_os.write(req1.getBytes());
-+ String reply = readline(proxy_is);
-+
-+ dbg("proxy replied: " + reply.trim());
-+
-+ if (reply.indexOf("HTTP/1.") == 0 && reply.indexOf(" 407 ") > 0) {
-+ proxy_auth = true;
-+ proxySock.close();
-+ } else if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
-+ proxySock.close();
-+ proxySock = psocket(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ dbg("2-a sadly, returning a null socket");
-+ return;
-+ }
-+ }
-+ } catch(Exception e) {
-+ dbg("some proxy socket problem: " + e.getMessage());
-+ }
-+
-+ /* read the rest of the HTTP headers */
-+ while (true) {
-+ String line = readline(proxy_is);
-+ dbg("proxy line: " + line.trim());
-+ if (proxy_auth) {
-+ String uc = line.toLowerCase();
-+ if (uc.indexOf("proxy-authenticate:") == 0) {
-+ if (uc.indexOf(" basic ") >= 0) {
-+ int idx = uc.indexOf(" realm");
-+ if (idx >= 0) {
-+ proxy_auth_basic_realm = uc.substring(idx+1);
-+ }
-+ }
-+ }
-+ }
-+ if (line.equals("\r\n") || line.equals("\n")) {
-+ break;
-+ }
-+ }
-+ if (!proxy_auth || proxy_auth_basic_realm.equals("")) {
-+ /* we only try once for the non-password case: */
-+ break;
-+ }
-+ }
-+ }
-+
-+ public SSLSocket proxy_socket(SSLSocketFactory factory) {
-+ Properties props = null;
-+ String proxyHost = null;
-+ int proxyPort = 0;
-+ String proxyHost_nossl = null;
-+ int proxyPort_nossl = 0;
-+ String str;
-+
-+ /* see if we can guess the proxy info from Properties: */
-+ try {
-+ props = System.getProperties();
-+ } catch (Exception e) {
-+ /* sandboxed applet might not be able to read it. */
-+ dbg("props failed: " + e.getMessage());
-+ }
-+ if (viewer.proxyHost != null) {
-+ dbg("Using supplied proxy " + viewer.proxyHost + " " + viewer.proxyPort + " applet parameters.");
-+ proxyHost = viewer.proxyHost;
-+ if (viewer.proxyPort != null) {
-+ proxyPort = gint(viewer.proxyPort);
-+ } else {
-+ proxyPort = 8080;
-+ }
-+
-+ } else if (props != null) {
-+ dbg("\n---------------\nAll props:");
-+ props.list(System.out);
-+ dbg("\n---------------\n\n");
-+
-+ /* scrape throught properties looking for proxy info: */
-+
-+ for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
-+ String s = (String) e.nextElement();
-+ String v = System.getProperty(s);
-+ String s2 = s.toLowerCase();
-+ String v2 = v.toLowerCase();
-+
-+ if (s2.indexOf("proxy.https.host") >= 0) {
-+ proxyHost = v2;
-+ continue;
-+ }
-+ if (s2.indexOf("proxy.https.port") >= 0) {
-+ proxyPort = gint(v2);
-+ continue;
-+ }
-+ if (s2.indexOf("proxy.http.host") >= 0) {
-+ proxyHost_nossl = v2;
-+ continue;
-+ }
-+ if (s2.indexOf("proxy.http.port") >= 0) {
-+ proxyPort_nossl = gint(v2);
-+ continue;
-+ }
-+ }
-+
-+ for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
-+ String s = (String) e.nextElement();
-+ String v = System.getProperty(s);
-+ String s2 = s.toLowerCase();
-+ String v2 = v.toLowerCase();
-+
-+ if (proxyHost != null && proxyPort > 0) {
-+ break;
-+ }
-+
-+ // look for something like: javaplugin.proxy.config.list = http=10.0.2.1:8082
-+ if (s2.indexOf("proxy") < 0 && v2.indexOf("proxy") < 0) {
-+ continue;
-+ }
-+ if (v2.indexOf("http") < 0) {
-+ continue;
-+ }
-+
-+ String[] pieces = v.split("[,;]");
-+ for (int i = 0; i < pieces.length; i++) {
-+ String p = pieces[i];
-+ int j = p.indexOf("https");
-+ if (j < 0) {
-+ j = p.indexOf("http");
-+ if (j < 0) {
-+ continue;
-+ }
-+ }
-+ j = p.indexOf("=", j);
-+ if (j < 0) {
-+ continue;
-+ }
-+ p = p.substring(j+1);
-+ String [] hp = p.split(":");
-+ if (hp.length != 2) {
-+ continue;
-+ }
-+ if (hp[0].length() > 1 && hp[1].length() > 1) {
-+
-+ proxyPort = gint(hp[1]);
-+ if (proxyPort < 0) {
-+ continue;
-+ }
-+ proxyHost = new String(hp[0]);
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ if (proxyHost != null) {
-+ if (proxyHost_nossl != null && proxyPort_nossl > 0) {
-+ dbg("Using http proxy info instead of https.");
-+ proxyHost = proxyHost_nossl;
-+ proxyPort = proxyPort_nossl;
-+ }
-+ }
-+
-+ if (proxy_in_use) {
-+ if (proxy_dialog_host != null && proxy_dialog_port > 0) {
-+ proxyHost = proxy_dialog_host;
-+ proxyPort = proxy_dialog_port;
-+ }
-+ if (proxyHost != null) {
-+ dbg("Lucky us! we figured out the Proxy parameters: " + proxyHost + " " + proxyPort);
-+ } else {
-+ /* ask user to help us: */
-+ ProxyDialog pd = new ProxyDialog(proxyHost, proxyPort);
-+ pd.queryUser();
-+ proxyHost = pd.getHost();
-+ proxyPort = pd.getPort();
-+ proxy_dialog_host = new String(proxyHost);
-+ proxy_dialog_port = proxyPort;
-+ dbg("User said host: " + pd.getHost() + " port: " + pd.getPort());
-+ }
-+
-+ proxy_helper(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ return null;
-+ }
-+ } else if (viewer.CONNECT != null) {
-+ dbg("viewer.CONNECT psocket:");
-+ proxySock = psocket(host, port);
-+ if (proxySock == null) {
-+ dbg("1-b sadly, returning a null socket");
-+ return null;
-+ }
-+ }
-+
-+ if (viewer.CONNECT != null) {
-+ String hp = viewer.CONNECT;
-+ String req2 = "CONNECT " + hp + " HTTP/1.1\r\n"
-+ + "Host: " + hp + "\r\n\r\n";
-+
-+ dbg("requesting2: " + req2);
-+
-+ try {
-+ proxy_os.write(req2.getBytes());
-+ String reply = readline(proxy_is);
-+
-+ dbg("proxy replied2: " + reply.trim());
-+
-+ if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
-+ proxySock.close();
-+ proxySock = psocket(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ dbg("2-b sadly, returning a null socket");
-+ return null;
-+ }
-+ }
-+ } catch(Exception e) {
-+ dbg("proxy socket problem-2: " + e.getMessage());
-+ }
-+
-+ while (true) {
-+ String line = readline(proxy_is);
-+ dbg("proxy line2: " + line.trim());
-+ if (line.equals("\r\n") || line.equals("\n")) {
-+ break;
-+ }
-+ }
-+ }
-+
-+ Socket sslsock = null;
-+ try {
-+ sslsock = factory.createSocket(proxySock, host, port, true);
-+ } catch(Exception e) {
-+ dbg("sslsock prob: " + e.getMessage());
-+ dbg("3 sadly, returning a null socket");
-+ }
-+
-+ return (SSLSocket) sslsock;
-+ }
-+
-+ Socket psocket(String h, int p) {
-+ Socket psock = null;
-+ try {
-+ psock = new Socket(h, p);
-+ proxy_is = new DataInputStream(new BufferedInputStream(
-+ psock.getInputStream(), 16384));
-+ proxy_os = psock.getOutputStream();
-+ } catch(Exception e) {
-+ dbg("psocket prob: " + e.getMessage());
-+ return null;
-+ }
-+
-+ return psock;
-+ }
-+
-+ String readline(DataInputStream i) {
-+ byte[] ba = new byte[1];
-+ String s = new String("");
-+ ba[0] = 0;
-+ try {
-+ while (ba[0] != 0xa) {
-+ ba[0] = (byte) i.readUnsignedByte();
-+ s += new String(ba);
-+ }
-+ } catch (Exception e) {
-+ ;
-+ }
-+ return s;
-+ }
-+}
-+
-+class TrustDialog implements ActionListener {
-+ String msg, host, text;
-+ int port;
-+ java.security.cert.Certificate[] trustallCerts = null;
-+ boolean viewing_cert = false;
-+ boolean trust_this_session = false;
-+
-+ /*
-+ * this is the gui to show the user the cert and info and ask
-+ * them if they want to continue using this cert.
-+ */
-+
-+ Button ok, cancel, viewcert;
-+ TextArea textarea;
-+ Checkbox accept, deny;
-+ Dialog dialog;
-+
-+ String s1 = "Accept this certificate temporarily for this session";
-+ String s2 = "Do not accept this certificate and do not connect to"
-+ + " this VNC server";
-+ String ln = "\n---------------------------------------------------\n\n";
-+
-+ TrustDialog (String h, int p, java.security.cert.Certificate[] s) {
-+ host = h;
-+ port = p;
-+ trustallCerts = s;
-+
-+ msg = "VNC Server " + host + ":" + port + " Not Verified";
-+ }
-+
-+ public boolean queryUser(String reason) {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame(msg);
-+
-+ dialog = new Dialog(frame, true);
-+
-+ String infostr = "";
-+ if (trustallCerts.length == 1) {
-+ CertInfo ci = new CertInfo(trustallCerts[0]);
-+ infostr = ci.get_certinfo("all");
-+ }
-+ if (reason != null) {
-+ reason += "\n\n";
-+ }
-+
-+ text = "\n"
-++ "Unable to verify the identity of\n"
-++ "\n"
-++ " " + host + ":" + port + "\n"
-++ "\n"
-++ infostr
-++ "\n"
-++ "as a trusted VNC server.\n"
-++ "\n"
-++ reason
-++ "In General not being able to verify the VNC Server and/or your seeing this Dialog\n"
-++ "is due to one of the following:\n"
-++ "\n"
-++ " - Your requesting to View the Certificate before accepting.\n"
-++ "\n"
-++ " - The VNC server is using a Self-Signed Certificate or a Certificate\n"
-++ " Authority not recognized by your Web Browser or Java Plugin runtime.\n"
-++ "\n"
-++ " - The use of an Apache SSL portal scheme employing CONNECT proxying AND\n"
-++ " the Apache Web server has a certificate *different* from the VNC server's.\n"
-++ "\n"
-++ " - No previously accepted Certificate (via Web Broswer/Java Plugin) could be\n"
-++ " obtained by this applet to compare the VNC Server Certificate against.\n"
-++ "\n"
-++ " - The VNC Server's Certificate does not match the one specified in the\n"
-++ " supplied 'serverCert' Java Applet Parameter.\n"
-++ "\n"
-++ " - A Man-In-The-Middle attack impersonating as the VNC server that you wish\n"
-++ " to connect to. (Wouldn't that be exciting!!)\n"
-++ "\n"
-++ "By safely copying the VNC server's Certificate (or using a common Certificate\n"
-++ "Authority certificate) you can configure your Web Browser and Java Plugin to\n"
-++ "automatically authenticate this VNC Server.\n"
-++ "\n"
-++ "If you do so, then you will only have to click \"Yes\" when this VNC Viewer\n"
-++ "applet asks you whether to trust your Browser/Java Plugin's acceptance of the\n"
-++ "certificate (except for the Apache portal case above where they don't match.)\n"
-++ "\n"
-++ "You can also set the applet parameter 'trustUrlVncCert=yes' to automatically\n"
-++ "accept certificates already accepted/trusted by your Web Browser/Java Plugin,\n"
-++ "and thereby see no dialog from this VNC Viewer applet.\n"
-+;
-+
-+ /* the accept / do-not-accept radio buttons: */
-+ CheckboxGroup checkbox = new CheckboxGroup();
-+ accept = new Checkbox(s1, true, checkbox);
-+ deny = new Checkbox(s2, false, checkbox);
-+
-+ /* put the checkboxes in a panel: */
-+ Panel check = new Panel();
-+ check.setLayout(new GridLayout(2, 1));
-+
-+ check.add(accept);
-+ check.add(deny);
-+
-+ /* make the 3 buttons: */
-+ ok = new Button("OK");
-+ cancel = new Button("Cancel");
-+ viewcert = new Button("View Certificate");
-+
-+ ok.addActionListener(this);
-+ cancel.addActionListener(this);
-+ viewcert.addActionListener(this);
-+
-+ /* put the buttons in their own panel: */
-+ Panel buttonrow = new Panel();
-+ buttonrow.setLayout(new FlowLayout(FlowLayout.LEFT));
-+ buttonrow.add(viewcert);
-+ buttonrow.add(ok);
-+ buttonrow.add(cancel);
-+
-+ /* label at the top: */
-+ Label label = new Label(msg, Label.CENTER);
-+ label.setFont(new Font("Helvetica", Font.BOLD, 16));
-+
-+ /* textarea in the middle */
-+ textarea = new TextArea(text, 38, 64,
-+ TextArea.SCROLLBARS_VERTICAL_ONLY);
-+ textarea.setEditable(false);
-+
-+ /* put the two panels in their own panel at bottom: */
-+ Panel bot = new Panel();
-+ bot.setLayout(new GridLayout(2, 1));
-+ bot.add(check);
-+ bot.add(buttonrow);
-+
-+ /* now arrange things inside the dialog: */
-+ dialog.setLayout(new BorderLayout());
-+
-+ dialog.add("North", label);
-+ dialog.add("South", bot);
-+ dialog.add("Center", textarea);
-+
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+
-+ return trust_this_session;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+
-+ if (evt.getSource() == viewcert) {
-+ /* View Certificate button clicked */
-+ if (viewing_cert) {
-+ /* show the original info text: */
-+ textarea.setText(text);
-+ viewcert.setLabel("View Certificate");
-+ viewing_cert = false;
-+ } else {
-+ int i;
-+ /* show all (likely just one) certs: */
-+ textarea.setText("");
-+ for (i=0; i < trustallCerts.length; i++) {
-+ int j = i + 1;
-+ textarea.append("Certificate[" +
-+ j + "]\n\n");
-+ textarea.append(
-+ trustallCerts[i].toString());
-+ textarea.append(ln);
-+ }
-+ viewcert.setLabel("View Info");
-+ viewing_cert = true;
-+
-+ textarea.setCaretPosition(0);
-+ }
-+
-+ } else if (evt.getSource() == ok) {
-+ /* OK button clicked */
-+ if (accept.getState()) {
-+ trust_this_session = true;
-+ } else {
-+ trust_this_session = false;
-+ }
-+ //dialog.dispose();
-+ dialog.hide();
-+
-+ } else if (evt.getSource() == cancel) {
-+ /* Cancel button clicked */
-+ trust_this_session = false;
-+
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+
-+ String get_certinfo() {
-+ String all = "";
-+ String fields[] = {"CN", "OU", "O", "L", "C"};
-+ int i;
-+ if (trustallCerts.length < 1) {
-+ all = "";
-+ return all;
-+ }
-+ String cert = trustallCerts[0].toString();
-+
-+ /*
-+ * For now we simply scrape the cert string, there must
-+ * be an API for this... perhaps optionValue?
-+ */
-+
-+ for (i=0; i < fields.length; i++) {
-+ int f, t, t1, t2;
-+ String sub, mat = fields[i] + "=";
-+
-+ f = cert.indexOf(mat, 0);
-+ if (f > 0) {
-+ t1 = cert.indexOf(", ", f);
-+ t2 = cert.indexOf("\n", f);
-+ if (t1 < 0 && t2 < 0) {
-+ continue;
-+ } else if (t1 < 0) {
-+ t = t2;
-+ } else if (t2 < 0) {
-+ t = t1;
-+ } else if (t1 < t2) {
-+ t = t1;
-+ } else {
-+ t = t2;
-+ }
-+ if (t > f) {
-+ sub = cert.substring(f, t);
-+ all = all + " " + sub + "\n";
-+ }
-+ }
-+ }
-+ return all;
-+ }
-+}
-+
-+class ProxyDialog implements ActionListener {
-+ String guessedHost = null;
-+ String guessedPort = null;
-+ /*
-+ * this is the gui to show the user the cert and info and ask
-+ * them if they want to continue using this cert.
-+ */
-+
-+ Button ok;
-+ Dialog dialog;
-+ TextField entry;
-+ String reply = "";
-+
-+ ProxyDialog (String h, int p) {
-+ guessedHost = h;
-+ try {
-+ guessedPort = Integer.toString(p);
-+ } catch (Exception e) {
-+ guessedPort = "8080";
-+ }
-+ }
-+
-+ public void queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Need Proxy host:port");
-+
-+ dialog = new Dialog(frame, true);
-+
-+
-+ Label label = new Label("Please Enter your https Proxy info as host:port", Label.CENTER);
-+ //label.setFont(new Font("Helvetica", Font.BOLD, 16));
-+ entry = new TextField(30);
-+ ok = new Button("OK");
-+ ok.addActionListener(this);
-+
-+ String guess = "";
-+ if (guessedHost != null) {
-+ guess = guessedHost + ":" + guessedPort;
-+ }
-+ entry.setText(guess);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", label);
-+ dialog.add("Center", entry);
-+ dialog.add("South", ok);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+ return;
-+ }
-+
-+ public String getHost() {
-+ int i = reply.indexOf(":");
-+ if (i < 0) {
-+ return "unknown";
-+ }
-+ String h = reply.substring(0, i);
-+ return h;
-+ }
-+
-+ public int getPort() {
-+ int i = reply.indexOf(":");
-+ int p = 8080;
-+ if (i < 0) {
-+ return p;
-+ }
-+ i++;
-+ String ps = reply.substring(i);
-+ try {
-+ Integer I = new Integer(ps);
-+ p = I.intValue();
-+ } catch (Exception e) {
-+ ;
-+ }
-+ return p;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == ok) {
-+ reply = entry.getText();
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+}
-+
-+class ProxyPasswdDialog implements ActionListener {
-+ String guessedHost = null;
-+ String guessedPort = null;
-+ String guessedUser = null;
-+ String guessedPasswd = null;
-+ String realm = null;
-+ /*
-+ * this is the gui to show the user the cert and info and ask
-+ * them if they want to continue using this cert.
-+ */
-+
-+ Button ok;
-+ Dialog dialog;
-+ TextField entry1;
-+ TextField entry2;
-+ String reply1 = "";
-+ String reply2 = "";
-+
-+ ProxyPasswdDialog (String h, int p, String realm) {
-+ guessedHost = h;
-+ try {
-+ guessedPort = Integer.toString(p);
-+ } catch (Exception e) {
-+ guessedPort = "8080";
-+ }
-+ this.realm = realm;
-+ }
-+
-+ public void queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Proxy Requires Username and Password");
-+
-+ dialog = new Dialog(frame, true);
-+
-+ //Label label = new Label("Please Enter your Web Proxy Username in the top Entry and Password in the bottom Entry", Label.CENTER);
-+ TextArea label = new TextArea("Please Enter your Web Proxy\nUsername in the Top Entry and\nPassword in the Bottom Entry,\nand then press OK.", 4, 20, TextArea.SCROLLBARS_NONE);
-+ entry1 = new TextField(30);
-+ entry2 = new TextField(30);
-+ entry2.setEchoChar('*');
-+ ok = new Button("OK");
-+ ok.addActionListener(this);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", label);
-+ dialog.add("Center", entry1);
-+ dialog.add("South", entry2);
-+ dialog.add("East", ok);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+ return;
-+ }
-+
-+ public String getAuth() {
-+ return reply1 + ":" + reply2;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == ok) {
-+ reply1 = entry1.getText();
-+ reply2 = entry2.getText();
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+}
-+
-+class ClientCertDialog implements ActionListener {
-+
-+ Button ok;
-+ Dialog dialog;
-+ TextField entry;
-+ String reply = "";
-+
-+ ClientCertDialog() {
-+ ;
-+ }
-+
-+ public String queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Enter SSL Client Cert+Key String");
-+
-+ dialog = new Dialog(frame, true);
-+
-+
-+ Label label = new Label("Please Enter the SSL Client Cert+Key String 308204c0...,...522d2d0a", Label.CENTER);
-+ entry = new TextField(30);
-+ ok = new Button("OK");
-+ ok.addActionListener(this);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", label);
-+ dialog.add("Center", entry);
-+ dialog.add("South", ok);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+ return reply;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == ok) {
-+ reply = entry.getText();
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+}
-+
-+class BrowserCertsDialog implements ActionListener {
-+ Button yes, no;
-+ Dialog dialog;
-+ String vncServer;
-+ String hostport;
-+ public boolean showCertDialog = true;
-+
-+ BrowserCertsDialog(String serv, String hp) {
-+ vncServer = serv;
-+ hostport = hp;
-+ }
-+
-+ public void queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Use Browser/JVM Certs?");
-+
-+ dialog = new Dialog(frame, true);
-+
-+ String m = "";
-+m += "\n";
-+m += "This VNC Viewer applet does not have its own keystore to track\n";
-+m += "SSL certificates, and so cannot authenticate the certificate\n";
-+m += "of the VNC Server:\n";
-+m += "\n";
-+m += " " + hostport + "\n\n " + vncServer + "\n";
-+m += "\n";
-+m += "on its own.\n";
-+m += "\n";
-+m += "However, it has noticed that your Web Browser and/or Java VM Plugin\n";
-+m += "has previously accepted the same certificate. You may have set\n";
-+m += "this up permanently or just for this session, or the server\n";
-+m += "certificate was signed by a CA cert that your Web Browser or\n";
-+m += "Java VM Plugin has.\n";
-+m += "\n";
-+m += "If the VNC Server connection times out while you are reading this\n";
-+m += "dialog, then restart the connection and try again.\n";
-+m += "\n";
-+m += "Should this VNC Viewer applet now connect to the above VNC server?\n";
-+m += "\n";
-+
-+ TextArea textarea = new TextArea(m, 22, 64,
-+ TextArea.SCROLLBARS_VERTICAL_ONLY);
-+ textarea.setEditable(false);
-+ yes = new Button("Yes");
-+ yes.addActionListener(this);
-+ no = new Button("No, Let Me See the Certificate.");
-+ no.addActionListener(this);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", textarea);
-+ dialog.add("Center", yes);
-+ dialog.add("South", no);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til Yes or No pressed. */
-+ System.out.println("done show()");
-+ return;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == yes) {
-+ showCertDialog = false;
-+ //dialog.dispose();
-+ dialog.hide();
-+ } else if (evt.getSource() == no) {
-+ showCertDialog = true;
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ System.out.println("done actionPerformed()");
-+ }
-+}
-+
-+class CertInfo {
-+ String fields[] = {"CN", "OU", "O", "L", "C"};
-+ java.security.cert.Certificate cert;
-+ String certString = "";
-+
-+ CertInfo(java.security.cert.Certificate c) {
-+ cert = c;
-+ certString = cert.toString();
-+ }
-+
-+ String get_certinfo(String which) {
-+ int i;
-+ String cs = new String(certString);
-+ String all = "";
-+
-+ /*
-+ * For now we simply scrape the cert string, there must
-+ * be an API for this... perhaps optionValue?
-+ */
-+ for (i=0; i < fields.length; i++) {
-+ int f, t, t1, t2;
-+ String sub, mat = fields[i] + "=";
-+
-+ f = cs.indexOf(mat, 0);
-+ if (f > 0) {
-+ t1 = cs.indexOf(", ", f);
-+ t2 = cs.indexOf("\n", f);
-+ if (t1 < 0 && t2 < 0) {
-+ continue;
-+ } else if (t1 < 0) {
-+ t = t2;
-+ } else if (t2 < 0) {
-+ t = t1;
-+ } else if (t1 < t2) {
-+ t = t1;
-+ } else {
-+ t = t2;
-+ }
-+ if (t > f) {
-+ sub = cs.substring(f, t);
-+ all = all + " " + sub + "\n";
-+ if (which.equals(fields[i])) {
-+ return sub;
-+ }
-+ }
-+ }
-+ }
-+ if (which.equals("all")) {
-+ return all;
-+ } else {
-+ return "";
-+ }
-+ }
-+}
-+
-+class Base64Coder {
-+
-+ // Mapping table from 6-bit nibbles to Base64 characters.
-+ private static char[] map1 = new char[64];
-+ static {
-+ int i=0;
-+ for (char c='A'; c<='Z'; c++) map1[i++] = c;
-+ for (char c='a'; c<='z'; c++) map1[i++] = c;
-+ for (char c='0'; c<='9'; c++) map1[i++] = c;
-+ map1[i++] = '+'; map1[i++] = '/'; }
-+
-+ // Mapping table from Base64 characters to 6-bit nibbles.
-+ private static byte[] map2 = new byte[128];
-+ static {
-+ for (int i=0; i<map2.length; i++) map2[i] = -1;
-+ for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
-+
-+ /**
-+ * Encodes a string into Base64 format.
-+ * No blanks or line breaks are inserted.
-+ * @param s a String to be encoded.
-+ * @return A String with the Base64 encoded data.
-+ */
-+ public static String encodeString (String s) {
-+ return new String(encode(s.getBytes())); }
-+
-+ /**
-+ * Encodes a byte array into Base64 format.
-+ * No blanks or line breaks are inserted.
-+ * @param in an array containing the data bytes to be encoded.
-+ * @return A character array with the Base64 encoded data.
-+ */
-+ public static char[] encode (byte[] in) {
-+ return encode(in,in.length); }
-+
-+ /**
-+ * Encodes a byte array into Base64 format.
-+ * No blanks or line breaks are inserted.
-+ * @param in an array containing the data bytes to be encoded.
-+ * @param iLen number of bytes to process in <code>in</code>.
-+ * @return A character array with the Base64 encoded data.
-+ */
-+ public static char[] encode (byte[] in, int iLen) {
-+ int oDataLen = (iLen*4+2)/3; // output length without padding
-+ int oLen = ((iLen+2)/3)*4; // output length including padding
-+ char[] out = new char[oLen];
-+ int ip = 0;
-+ int op = 0;
-+ while (ip < iLen) {
-+ int i0 = in[ip++] & 0xff;
-+ int i1 = ip < iLen ? in[ip++] & 0xff : 0;
-+ int i2 = ip < iLen ? in[ip++] & 0xff : 0;
-+ int o0 = i0 >>> 2;
-+ int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
-+ int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
-+ int o3 = i2 & 0x3F;
-+ out[op++] = map1[o0];
-+ out[op++] = map1[o1];
-+ out[op] = op < oDataLen ? map1[o2] : '='; op++;
-+ out[op] = op < oDataLen ? map1[o3] : '='; op++; }
-+ return out; }
-+
-+ /**
-+ * Decodes a string from Base64 format.
-+ * @param s a Base64 String to be decoded.
-+ * @return A String containing the decoded data.
-+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
-+ */
-+ public static String decodeString (String s) {
-+ return new String(decode(s)); }
-+
-+ /**
-+ * Decodes a byte array from Base64 format.
-+ * @param s a Base64 String to be decoded.
-+ * @return An array containing the decoded data bytes.
-+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
-+ */
-+ public static byte[] decode (String s) {
-+ return decode(s.toCharArray()); }
-+
-+ /**
-+ * Decodes a byte array from Base64 format.
-+ * No blanks or line breaks are allowed within the Base64 encoded data.
-+ * @param in a character array containing the Base64 encoded data.
-+ * @return An array containing the decoded data bytes.
-+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
-+ */
-+ public static byte[] decode (char[] in) {
-+ int iLen = in.length;
-+ if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
-+ while (iLen > 0 && in[iLen-1] == '=') iLen--;
-+ int oLen = (iLen*3) / 4;
-+ byte[] out = new byte[oLen];
-+ int ip = 0;
-+ int op = 0;
-+ while (ip < iLen) {
-+ int i0 = in[ip++];
-+ int i1 = in[ip++];
-+ int i2 = ip < iLen ? in[ip++] : 'A';
-+ int i3 = ip < iLen ? in[ip++] : 'A';
-+ if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
-+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
-+ int b0 = map2[i0];
-+ int b1 = map2[i1];
-+ int b2 = map2[i2];
-+ int b3 = map2[i3];
-+ if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
-+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
-+ int o0 = ( b0 <<2) | (b1>>>4);
-+ int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
-+ int o2 = ((b2 & 3)<<6) | b3;
-+ out[op++] = (byte)o0;
-+ if (op<oLen) out[op++] = (byte)o1;
-+ if (op<oLen) out[op++] = (byte)o2; }
-+ return out; }
-+
-+ // Dummy constructor.
-+ private Base64Coder() {}
-+
-+}
-diff -Naur vnc_javasrc.orig/VncCanvas.java vnc_javasrc/VncCanvas.java
---- vnc_javasrc.orig/VncCanvas.java 2004-10-10 02:15:54.000000000 -0400
-+++ vnc_javasrc/VncCanvas.java 2010-11-30 21:01:15.000000000 -0500
-@@ -28,13 +28,14 @@
- import java.lang.*;
- import java.util.zip.*;
-
-+import java.util.Collections;
-
- //
- // VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
- //
-
- class VncCanvas extends Canvas
-- implements KeyListener, MouseListener, MouseMotionListener {
-+ implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {
-
- VncViewer viewer;
- RfbProto rfb;
-@@ -81,6 +82,20 @@
- cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
- cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
-
-+ // kludge to not show any Java cursor in the canvas since we are
-+ // showing the soft cursor (should be a user setting...)
-+ Cursor dot = Toolkit.getDefaultToolkit().createCustomCursor(
-+ Toolkit.getDefaultToolkit().createImage(new byte[4]), new Point(0,0),
-+ "dot");
-+ this.setCursor(dot);
-+
-+ // while we are at it... get rid of the keyboard traversals that
-+ // make it so we can't type a Tab character:
-+ this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
-+ Collections.EMPTY_SET);
-+ this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
-+ Collections.EMPTY_SET);
-+
- colors = new Color[256];
- for (int i = 0; i < 256; i++)
- colors[i] = new Color(cm8.getRGB(i));
-@@ -169,6 +184,7 @@
- inputEnabled = true;
- addMouseListener(this);
- addMouseMotionListener(this);
-+ addMouseWheelListener(this);
- if (viewer.showControls) {
- viewer.buttonPanel.enableRemoteAccessControls(true);
- }
-@@ -177,6 +193,7 @@
- inputEnabled = false;
- removeMouseListener(this);
- removeMouseMotionListener(this);
-+ removeMouseWheelListener(this);
- if (viewer.showControls) {
- viewer.buttonPanel.enableRemoteAccessControls(false);
- }
-@@ -1190,6 +1207,9 @@
- public void mouseDragged(MouseEvent evt) {
- processLocalMouseEvent(evt, true);
- }
-+ public void mouseWheelMoved(MouseWheelEvent evt) {
-+ processLocalMouseWheelEvent(evt);
-+ }
-
- public void processLocalKeyEvent(KeyEvent evt) {
- if (viewer.rfb != null && rfb.inNormalProtocol) {
-@@ -1221,6 +1241,19 @@
- evt.consume();
- }
-
-+ public void processLocalMouseWheelEvent(MouseWheelEvent evt) {
-+ if (viewer.rfb != null && rfb.inNormalProtocol) {
-+ synchronized(rfb) {
-+ try {
-+ rfb.writeWheelEvent(evt);
-+ } catch (Exception e) {
-+ e.printStackTrace();
-+ }
-+ rfb.notify();
-+ }
-+ }
-+ }
-+
- public void processLocalMouseEvent(MouseEvent evt, boolean moved) {
- if (viewer.rfb != null && rfb.inNormalProtocol) {
- if (moved) {
-@@ -1387,9 +1420,9 @@
- result = cm8.getRGB(pixBuf[i]);
- } else {
- result = 0xFF000000 |
-- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
-- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
-- (pixBuf[i * 4 + 3] & 0xFF);
-+ (pixBuf[i * 4 + 2] & 0xFF) << 16 |
-+ (pixBuf[i * 4 + 1] & 0xFF) << 8 |
-+ (pixBuf[i * 4 + 0] & 0xFF);
- }
- } else {
- result = 0; // Transparent pixel
-@@ -1403,9 +1436,9 @@
- result = cm8.getRGB(pixBuf[i]);
- } else {
- result = 0xFF000000 |
-- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
-- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
-- (pixBuf[i * 4 + 3] & 0xFF);
-+ (pixBuf[i * 4 + 2] & 0xFF) << 16 |
-+ (pixBuf[i * 4 + 1] & 0xFF) << 8 |
-+ (pixBuf[i * 4 + 0] & 0xFF);
- }
- } else {
- result = 0; // Transparent pixel
-diff -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncViewer.java
---- vnc_javasrc.orig/VncViewer.java 2004-03-04 08:34:25.000000000 -0500
-+++ vnc_javasrc/VncViewer.java 2010-03-27 17:57:04.000000000 -0400
-@@ -29,6 +29,7 @@
- import java.awt.event.*;
- import java.io.*;
- import java.net.*;
-+import java.util.*;
-
- public class VncViewer extends java.applet.Applet
- implements java.lang.Runnable, WindowListener {
-@@ -80,7 +81,7 @@
- // Variables read from parameter values.
- String socketFactory;
- String host;
-- int port;
-+ int port, vncserverport;
- boolean showControls;
- boolean offerRelogin;
- boolean showOfflineDesktop;
-@@ -88,6 +89,24 @@
- int deferCursorUpdates;
- int deferUpdateRequests;
-
-+ boolean disableSSL;
-+ boolean GET;
-+ String CONNECT;
-+ String urlPrefix;
-+ String httpsPort;
-+ String oneTimeKey;
-+ String serverCert;
-+ String proxyHost;
-+ String proxyPort;
-+ boolean forceProxy;
-+ boolean ignoreProxy;
-+ boolean trustAllVncCerts;
-+ boolean trustUrlVncCert;
-+ boolean debugCerts;
-+ boolean debugKeyboard;
-+ boolean mapF5_to_atsign;
-+ boolean forbid_Ctrl_Alt;
-+
- // Reference to this applet for inter-applet communication.
- public static java.applet.Applet refApplet;
-
-@@ -282,10 +301,24 @@
- validate();
- }
-
-- while (!tryAuthenticate()) {
-- authenticator.retry();
-- authenticatorUnixLogin.retry();
-- }
-+ if (false) {
-+ /* a bug on retries: 'Error: bad position: 8' sun.awt.X11.XTextFieldPeer.setCaretPosition(XTextFieldPeer.java:215) */
-+ while (!tryAuthenticate()) {
-+ authenticator.retry();
-+ authenticatorUnixLogin.retry();
-+ }
-+ } else {
-+ /* just try once and not forever... */
-+ if (!tryAuthenticate()) {
-+ showConnectionStatus("Authentication Failed.");
-+ showMessage("Authentication Failed.");
-+ if (!offerRelogin) {
-+ fatalError("auth failed.");
-+ }
-+ } else {
-+ //showConnectionStatus("Authentication OK.");
-+ }
-+ }
- }
-
-
-@@ -428,7 +461,10 @@
- gbc.ipadx = 100;
- gbc.ipady = 50;
- gridbag.setConstraints(authPanel, gbc);
-+ try {
- vncContainer.add(authPanel);
-+ } catch (Exception e) {
-+ }
-
- if (inSeparateFrame) {
- vncFrame.pack();
-@@ -590,9 +626,28 @@
- fatalError("HOST parameter not specified");
- }
- }
-+ Date d = new Date();
-+ System.out.println("-\nSSL VNC Java Applet starting. " + d);
-
-- String str = readParameter("PORT", true);
-- port = Integer.parseInt(str);
-+ port = 0;
-+ String str = readParameter("PORT", false);
-+ if (str != null) {
-+ port = Integer.parseInt(str);
-+ }
-+ // When there is a proxy VNCSERVERPORT may be inaccessible (inside firewall).
-+ vncserverport = 0;
-+ str = readParameter("VNCSERVERPORT", false);
-+ if (str != null) {
-+ vncserverport = Integer.parseInt(str);
-+ }
-+ if (port == 0 && vncserverport == 0) {
-+ fatalError("Neither PORT nor VNCSERVERPORT parameters specified");
-+ }
-+ if (port == 0) {
-+ // Nevertheless, fall back to vncserverport if we have to.
-+ System.out.println("using vncserverport: '" + vncserverport + "' for PORT.");
-+ port = vncserverport;
-+ }
-
- if (inAnApplet) {
- str = readParameter("Open New Window", false);
-@@ -626,6 +681,121 @@
-
- // SocketFactory.
- socketFactory = readParameter("SocketFactory", false);
-+
-+ // SSL
-+ disableSSL = false;
-+ str = readParameter("DisableSSL", false);
-+ if (str != null && str.equalsIgnoreCase("Yes"))
-+ disableSSL = true;
-+
-+ httpsPort = readParameter("httpsPort", false);
-+
-+ // Extra GET, CONNECT string:
-+ CONNECT = readParameter("CONNECT", false);
-+ if (CONNECT != null) {
-+ CONNECT = CONNECT.replaceAll(" ", ":");
-+ }
-+
-+ GET = false;
-+ str = readParameter("GET", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ GET = true;
-+ }
-+ if (str != null && str.equalsIgnoreCase("1")) {
-+ GET = true;
-+ }
-+
-+ urlPrefix = readParameter("urlPrefix", false);
-+ if (urlPrefix != null) {
-+ urlPrefix = urlPrefix.replaceAll("%2F", "/");
-+ urlPrefix = urlPrefix.replaceAll("%2f", "/");
-+ urlPrefix = urlPrefix.replaceAll("_2F_", "/");
-+ if (urlPrefix.indexOf("/") != 0) {
-+ urlPrefix = "/" + urlPrefix;
-+ }
-+ } else {
-+ urlPrefix = "";
-+ }
-+ System.out.println("urlPrefix: '" + urlPrefix + "'");
-+
-+ oneTimeKey = readParameter("oneTimeKey", false);
-+ if (oneTimeKey != null) {
-+ System.out.println("oneTimeKey is set.");
-+ }
-+
-+ serverCert = readParameter("serverCert", false);
-+ if (serverCert != null) {
-+ System.out.println("serverCert is set.");
-+ }
-+
-+ forceProxy = false;
-+ proxyHost = null;
-+ proxyPort = null;
-+ str = readParameter("forceProxy", false);
-+ if (str != null) {
-+ if (str.equalsIgnoreCase("Yes")) {
-+ forceProxy = true;
-+ } else if (str.equalsIgnoreCase("No")) {
-+ forceProxy = false;
-+ } else {
-+ forceProxy = true;
-+ String[] pieces = str.split(" ");
-+ proxyHost = new String(pieces[0]);
-+ if (pieces.length >= 2) {
-+ proxyPort = new String(pieces[1]);
-+ } else {
-+ proxyPort = new String("8080");
-+ }
-+ }
-+ }
-+ str = readParameter("proxyHost", false);
-+ if (str != null) {
-+ proxyHost = new String(str);
-+ }
-+ str = readParameter("proxyPort", false);
-+ if (str != null) {
-+ proxyPort = new String(str);
-+ }
-+ if (proxyHost != null && proxyPort == null) {
-+ proxyPort = new String("8080");
-+ }
-+
-+ ignoreProxy = false;
-+ str = readParameter("ignoreProxy", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ ignoreProxy = true;
-+ }
-+
-+ trustAllVncCerts = false;
-+ str = readParameter("trustAllVncCerts", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ trustAllVncCerts = true;
-+ }
-+ trustUrlVncCert = false;
-+ str = readParameter("trustUrlVncCert", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ trustUrlVncCert = true;
-+ }
-+ debugCerts = false;
-+ str = readParameter("debugCerts", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ debugCerts = true;
-+ }
-+ debugKeyboard = false;
-+ str = readParameter("debugKeyboard", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ debugKeyboard = true;
-+ }
-+ mapF5_to_atsign = false;
-+ str = readParameter("mapF5_to_atsign", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ mapF5_to_atsign = true;
-+ }
-+ forbid_Ctrl_Alt = false;
-+ str = readParameter("forbid_Ctrl_Alt", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ forbid_Ctrl_Alt = true;
-+ }
- }
-
- public String readParameter(String name, boolean required) {
diff --git a/classes/ssl/ultra.vnc b/classes/ssl/ultra.vnc
deleted file mode 100644
index 3c57445..0000000
--- a/classes/ssl/ultra.vnc
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- index.vnc - default HTML page for TightVNC Java viewer applet, to be
- used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
- Xvnc will substitute the following variables when preceded by a dollar:
- USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
- PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
- HTML page.
-
- NOTE: the $PARAMS variable is not supported by the standard VNC, so
- make sure you have TightVNC on the server side, if you're using this
- variable.
--->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=UltraViewerSSL.jar
- WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name="Open New Window" value=yes>
-<param name="ignoreMSLogonCheck" value=yes>
-<param name="delayAuthPanel" value=yes>
-$PARAMS
-</APPLET>
-<BR>
-<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
-</HTML>
diff --git a/classes/ssl/ultraproxy.vnc b/classes/ssl/ultraproxy.vnc
deleted file mode 100644
index fd842c4..0000000
--- a/classes/ssl/ultraproxy.vnc
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- index.vnc - default HTML page for TightVNC Java viewer applet, to be
- used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
- Xvnc will substitute the following variables when preceded by a dollar:
- USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
- PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
- HTML page.
-
- NOTE: the $PARAMS variable is not supported by the standard VNC, so
- make sure you have TightVNC on the server side, if you're using this
- variable.
--->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=SignedUltraViewerSSL.jar
- WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name="Open New Window" value=yes>
-<param name="ignoreMSLogonCheck" value=yes>
-<param name="delayAuthPanel" value=yes>
-<param name=VNCSERVERPORT value=$PORT>
-$PARAMS
-</APPLET>
-<BR>
-<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
-</HTML>
diff --git a/classes/ssl/ultrasigned.vnc b/classes/ssl/ultrasigned.vnc
deleted file mode 100644
index a711655..0000000
--- a/classes/ssl/ultrasigned.vnc
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- index.vnc - default HTML page for TightVNC Java viewer applet, to be
- used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
- Xvnc will substitute the following variables when preceded by a dollar:
- USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
- PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
- HTML page.
-
- NOTE: the $PARAMS variable is not supported by the standard VNC, so
- make sure you have TightVNC on the server side, if you're using this
- variable.
--->
-
-<HTML>
-<TITLE>
-$USER's $DESKTOP desktop ($DISPLAY)
-</TITLE>
-<APPLET CODE=VncViewer.class ARCHIVE=SignedUltraViewerSSL.jar
- WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
-<param name=PORT value=$PORT>
-<param name="Open New Window" value=yes>
-<param name="ignoreMSLogonCheck" value=yes>
-<param name="delayAuthPanel" value=yes>
-$PARAMS
-</APPLET>
-<BR>
-<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
-</HTML>
diff --git a/classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch b/classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch
deleted file mode 100644
index 3309860..0000000
--- a/classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch
+++ /dev/null
@@ -1,5494 +0,0 @@
-diff -Naur JavaViewer.orig/ButtonPanel.java JavaViewer/ButtonPanel.java
---- JavaViewer.orig/ButtonPanel.java 2004-12-12 20:51:02.000000000 -0500
-+++ JavaViewer/ButtonPanel.java 2007-05-31 15:40:45.000000000 -0400
-@@ -43,30 +43,36 @@
- viewer = v;
-
- setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-- disconnectButton = new Button("Disconnect");
-+ if (v.ftpOnly) {
-+ disconnectButton = new Button("Quit");
-+ } else {
-+ disconnectButton = new Button("Close");
-+ }
- disconnectButton.setEnabled(false);
- add(disconnectButton);
- disconnectButton.addActionListener(this);
-- optionsButton = new Button("Options");
-- add(optionsButton);
-- optionsButton.addActionListener(this);
-- clipboardButton = new Button("Clipboard");
-- clipboardButton.setEnabled(false);
-- add(clipboardButton);
-- clipboardButton.addActionListener(this);
-- if (viewer.rec != null) {
-- recordButton = new Button("Record");
-- add(recordButton);
-- recordButton.addActionListener(this);
-- }
-- ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
-- ctrlAltDelButton.setEnabled(false);
-- add(ctrlAltDelButton);
-- ctrlAltDelButton.addActionListener(this);
-- refreshButton = new Button("Refresh");
-- refreshButton.setEnabled(false);
-- add(refreshButton);
-- refreshButton.addActionListener(this);
-+ if (!v.ftpOnly) {
-+ optionsButton = new Button("Options");
-+ add(optionsButton);
-+ optionsButton.addActionListener(this);
-+ clipboardButton = new Button("Clipboard");
-+ clipboardButton.setEnabled(false);
-+ add(clipboardButton);
-+ clipboardButton.addActionListener(this);
-+ if (viewer.rec != null) {
-+ recordButton = new Button("Record");
-+ add(recordButton);
-+ recordButton.addActionListener(this);
-+ }
-+ ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
-+ ctrlAltDelButton.setEnabled(false);
-+ add(ctrlAltDelButton);
-+ ctrlAltDelButton.addActionListener(this);
-+ refreshButton = new Button("Refresh");
-+ refreshButton.setEnabled(false);
-+ add(refreshButton);
-+ refreshButton.addActionListener(this);
-+ }
- ftpButton = new Button("File Transfer");
- ftpButton.setEnabled(false);
- add(ftpButton);
-@@ -79,9 +85,10 @@
-
- public void enableButtons() {
- disconnectButton.setEnabled(true);
-+ ftpButton.setEnabled(true);
-+ if (viewer.ftpOnly) {return;}
- clipboardButton.setEnabled(true);
- refreshButton.setEnabled(true);
-- ftpButton.setEnabled(true);
- }
-
- //
-@@ -89,6 +96,9 @@
- //
-
- public void disableButtonsOnDisconnect() {
-+ ftpButton.setEnabled(false);
-+ if (viewer.ftpOnly) {return;}
-+
- remove(disconnectButton);
- disconnectButton = new Button("Hide desktop");
- disconnectButton.setEnabled(true);
-@@ -99,7 +109,6 @@
- clipboardButton.setEnabled(false);
- ctrlAltDelButton.setEnabled(false);
- refreshButton.setEnabled(false);
-- ftpButton.setEnabled(false);
-
- validate();
- }
-@@ -110,6 +119,7 @@
- //
-
- public void enableRemoteAccessControls(boolean enable) {
-+ if (viewer.ftpOnly) {return;}
- ctrlAltDelButton.setEnabled(enable);
- }
-
-@@ -163,9 +173,19 @@
- }
- else if (evt.getSource() == ftpButton)
- {
-- viewer.ftp.setVisible(!viewer.ftp.isVisible());
-+// begin runge/x11vnc
-+ if (viewer.ftpOnly) {
-+ viewer.vncFrame.setVisible(false);
-+ }
-+ viewer.ftp.setSavedLocations();
-+ if (viewer.ftp.isVisible()) {
-+ viewer.ftp.doClose();
-+ } else {
-+ viewer.ftp.doOpen();
-+ }
-+// end runge/x11vnc
- viewer.rfb.readServerDriveList();
--
-+
- }
- }
- }
-diff -Naur JavaViewer.orig/FTPFrame.java JavaViewer/FTPFrame.java
---- JavaViewer.orig/FTPFrame.java 2005-03-15 23:53:14.000000000 -0500
-+++ JavaViewer/FTPFrame.java 2009-01-13 09:48:30.000000000 -0500
-@@ -24,8 +24,17 @@
- import java.io.*;
- import java.util.ArrayList;
- import java.util.Vector;
-+import java.util.Date;
- import javax.swing.*;
-
-+import java.nio.ByteBuffer;
-+import java.nio.CharBuffer;
-+import java.nio.charset.*;
-+
-+// begin runge/x11vnc
-+import java.util.Arrays;
-+// end runge/x11vnc
-+
-
- /*
- * Created on Feb 25, 2004
-@@ -74,12 +83,31 @@
- public javax.swing.JTextField connectionStatus = null;
- public boolean updateDriveList;
- private Vector remoteList = null;
-+ private Vector remoteListInfo = null;
- private Vector localList = null;
-+ private Vector localListInfo = null;
- private File currentLocalDirectory = null; // Holds the current local Directory
- private File currentRemoteDirectory = null; // Holds the current remote Directory
- private File localSelection = null; // Holds the currently selected local file
- private String remoteSelection = null; // Holds the currently selected remote file
- public String selectedTable = null;
-+
-+// begin runge/x11vnc
-+ private javax.swing.JButton viewButton = null;
-+ private javax.swing.JButton refreshButton = null;
-+ public File saveLocalDirectory = null;
-+ public long saveLocalDirectoryTime = 0;
-+ public int saveLocalDirectoryCount = 0;
-+ public String saveRemoteDirectory = null;
-+ public long saveRemoteDirectoryTime = 0;
-+ public int saveRemoteDirectoryCount = 0;
-+ private boolean localCurrentIsDir = true;
-+ private int lastRemoteIndex = -1;
-+ private int lastLocalIndex = -1;
-+ private boolean doingShortcutDir = false;
-+ private boolean gotShortcutDir = false;
-+ private boolean ignore_events = false;
-+// end runge/x11vnc
-
- // sf@2004 - Separate directories and files for better lisibility
- private ArrayList DirsList;
-@@ -125,11 +153,61 @@
-
- void refreshRemoteLocation()
- {
-+
-+//System.out.println("refreshRemoteLocation1");
- remoteList.clear();
-+ remoteListInfo.clear();
- remoteFileTable.setListData(remoteList);
-+System.out.println("refreshRemoteLocation '" + remoteLocation.getText() + "'"); // runge/x11vnc
- viewer.rfb.readServerDirectory(remoteLocation.getText());
- }
-
-+// begin runge/x11vnc
-+ public void setSavedLocations() {
-+ saveLocalDirectory = currentLocalDirectory;
-+ saveLocalDirectoryTime = System.currentTimeMillis();
-+ saveLocalDirectoryCount = 0;
-+
-+ if (remoteLocation != null) {
-+ saveRemoteDirectory = remoteLocation.getText();
-+System.out.println("RemoteSave '" + saveRemoteDirectory + "'");
-+ }
-+ saveRemoteDirectoryTime = System.currentTimeMillis();
-+ saveRemoteDirectoryCount = 0;
-+ }
-+
-+ private File saveLocalHack(File dir) {
-+ saveLocalDirectoryCount++;
-+//System.out.println("L " + saveLocalDirectoryCount + " dt: " + (System.currentTimeMillis() - saveLocalDirectoryTime) + " - " + saveLocalDirectory);
-+ if (System.currentTimeMillis() > saveLocalDirectoryTime + 2000 || saveLocalDirectoryCount > 2) {
-+ saveLocalDirectory = null;
-+ }
-+ if (saveLocalDirectory != null) {
-+ currentLocalDirectory = saveLocalDirectory;
-+ localLocation.setText(saveLocalDirectory.toString());
-+ return saveLocalDirectory;
-+ } else {
-+ return dir;
-+ }
-+ }
-+
-+ private String saveRemoteHack(String indrive) {
-+ saveRemoteDirectoryCount++;
-+//System.out.println("R " + saveRemoteDirectoryCount + " - " + saveRemoteDirectory);
-+ if (saveRemoteDirectory != null && saveRemoteDirectoryCount > 1) {
-+ saveRemoteDirectory = null;
-+ }
-+ if (saveRemoteDirectory != null) {
-+ if (! saveRemoteDirectory.equals("")) {
-+System.out.println("saveRemoteHack setText + refreshRemoteLocation '" + saveRemoteDirectory + "'");
-+ return saveRemoteDirectory;
-+ }
-+ }
-+ return indrive;
-+ }
-+// end runge/x11vnc
-+
-+
- /*
- * Prints the list of drives on the remote directory and returns a String[].
- * str takes as string like A:fC:lD:lE:lF:lG:cH:c
-@@ -143,6 +221,9 @@
- int size = str.length();
- String driveType = null;
- String[] drive = new String[str.length() / 3];
-+ int idx = 0, C_drive = -1, O_drive = -1;
-+
-+System.out.println("ComboBox: Str '" + str + "'");
-
- // Loop through the string to create a String[]
- for (int i = 0; i < size; i = i + 3) {
-@@ -150,26 +231,68 @@
- driveType = str.substring(i + 2, i + 3);
- if (driveType.compareTo("f") == 0)
- drive[i / 3] += "\\ Floppy";
-- if (driveType.compareTo("l") == 0)
-+ if (driveType.compareTo("l") == 0) {
- drive[i / 3] += "\\ Local Disk";
-+ if (drive[i/3].substring(0,1).toUpperCase().equals("C")) {
-+ C_drive = idx;
-+ } else if (O_drive < 0) {
-+ O_drive = idx;
-+ }
-+ }
- if (driveType.compareTo("c") == 0)
- drive[i / 3] += "\\ CD-ROM";
- if (driveType.compareTo("n") == 0)
- drive[i / 3] += "\\ Network";
-
- remoteDrivesComboBox.addItem(drive[i / 3]);
-+System.out.println("ComboBox: Add " + idx + " '" + drive[i/3] + "'");
-+ idx++;
-+ }
-+
-+ // runge
-+ if (viewer.ftpDropDown != null) {
-+ String[] dd = viewer.ftpDropDown.split("\\.");
-+ for (int i=0; i < dd.length; i++) {
-+ if (!dd[i].equals("")) {
-+ String s = dd[i];
-+ if (s.startsWith("TOP_")) {
-+ s = s.substring(4);
-+ remoteDrivesComboBox.insertItemAt(" [" + s + "]", 0);
-+ } else {
-+ remoteDrivesComboBox.addItem(" [" + s + "]");
-+ }
-+ }
-+ }
-+ } else {
-+ remoteDrivesComboBox.addItem(" [My Documents]");
-+ remoteDrivesComboBox.addItem(" [Desktop]");
-+ remoteDrivesComboBox.addItem(" [Home]");
- }
-+
- //sf@ - Select Drive C:as default if possible
- boolean bFound = false;
-- for(int i = 0; i < remoteDrivesComboBox.getItemCount() ; i++)
-- {
-- if(remoteDrivesComboBox.getItemAt(i).toString().substring(0,1).toUpperCase().equals("C"))
-- {
-- remoteDrivesComboBox.setSelectedIndex(i);
-+
-+ if (false) {
-+ for(int i = 0; i < remoteDrivesComboBox.getItemCount() ; i++) {
-+ if(remoteDrivesComboBox.getItemAt(i).toString().substring(0,1).toUpperCase().equals("C")) {
-+ remoteDrivesComboBox.setSelectedIndex(i);
-+ bFound = true;
-+ }
-+ }
-+ } else {
-+ if (C_drive >= 0) {
-+ remoteDrivesComboBox.setSelectedIndex(C_drive);
-+ bFound = true;
-+System.out.println("ComboBox: C_drive index: " + C_drive);
-+ } else if (O_drive >= 0) {
-+ remoteDrivesComboBox.setSelectedIndex(O_drive);
- bFound = true;
-+System.out.println("ComboBox: Other_drive index: " + O_drive);
- }
- }
-+
- if (!bFound) remoteDrivesComboBox.setSelectedIndex(0);
-+
- updateDriveList = false;
- return drive;
- }
-@@ -185,6 +308,8 @@
- stopButton.setVisible(true);
- stopButton.setEnabled(true);
- receiveButton.setEnabled(false);
-+ viewButton.setEnabled(false); // runge/x11vnc
-+ refreshButton.setEnabled(false);
- remoteTopButton.setEnabled(false);
- sendButton.setEnabled(false);
- remoteFileTable.setEnabled(false);
-@@ -207,6 +332,8 @@
- stopButton.setVisible(false);
- stopButton.setEnabled(false);
- receiveButton.setEnabled(true);
-+ viewButton.setEnabled(true); // runge/x11vnc
-+ refreshButton.setEnabled(true);
- remoteTopButton.setEnabled(true);
- sendButton.setEnabled(true);
- remoteFileTable.setEnabled(true);
-@@ -221,10 +348,11 @@
- /*
- * Print Directory prints out all the contents of a directory
- */
-- void printDirectory(ArrayList a) {
-+ void printDirectory(ArrayList a, ArrayList b) {
-
- for (int i = 0; i < a.size(); i++) {
- remoteList.addElement(a.get(i));
-+ remoteListInfo.addElement(b.get(i));
- }
- remoteFileTable.setListData(remoteList);
- }
-@@ -235,10 +363,12 @@
- * @return void
- */
- private void initialize() {
-+ ignore_events = true;
- this.setSize(794, 500);
- this.setContentPane(getJContentPane());
-+ ignore_events = false;
- updateDriveList = true;
-- }
-+ }
- /**
- * This method initializes jContentPane. This is the main content pane
- *
-@@ -253,6 +383,33 @@
- jContentPane.add(getRemotePanel(), java.awt.BorderLayout.EAST);
- jContentPane.add(getLocalPanel(), java.awt.BorderLayout.WEST);
- jContentPane.add(getButtonPanel(), java.awt.BorderLayout.CENTER);
-+
-+ KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
-+ AbstractAction escapeAction = new AbstractAction() {
-+ public void actionPerformed(ActionEvent actionEvent) {
-+ System.out.println("Escape Pressed");
-+ if (viewer.ftpOnly) {
-+ System.out.println("exiting...");
-+ System.exit(0);
-+ } else {
-+ doClose();
-+ }
-+ }
-+ };
-+ jContentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "escapeAction");
-+ jContentPane.getInputMap().put(stroke, "escapeAction");
-+ jContentPane.getActionMap().put("escapeAction", escapeAction);
-+
-+ stroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK);
-+ AbstractAction resetAction = new AbstractAction() {
-+ public void actionPerformed(ActionEvent actionEvent) {
-+ System.out.println("Ctrl-R Pressed");
-+ doReset();
-+ }
-+ };
-+ jContentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "resetAction");
-+ jContentPane.getInputMap().put(stroke, "resetAction");
-+ jContentPane.getActionMap().put("resetAction", resetAction);
- }
- return jContentPane;
- }
-@@ -270,6 +427,7 @@
- topPanelLocal.add(getLocalMachineLabel(), java.awt.BorderLayout.CENTER);
- topPanelLocal.add(getLocalTopButton(), java.awt.BorderLayout.EAST);
- topPanelLocal.setBackground(java.awt.Color.lightGray);
-+//System.out.println("getTopPanelLocal");
- }
- return topPanelLocal;
- }
-@@ -288,6 +446,7 @@
- topPanelRemote.add(getRemoteMachineLabel(), java.awt.BorderLayout.CENTER);
- topPanelRemote.add(getRemoteTopButton(), java.awt.BorderLayout.EAST);
- topPanelRemote.setBackground(java.awt.Color.lightGray);
-+//System.out.println("getTopPanelRemote");
- }
- return topPanelRemote;
- }
-@@ -301,6 +460,7 @@
- if (topPanelCenter == null) {
- topPanelCenter = new javax.swing.JPanel();
- topPanelCenter.add(getDummyButton(), null);
-+//System.out.println("getTopPanelCenter");
- }
- return topPanelCenter;
- }
-@@ -328,6 +488,7 @@
- topPanel.add(getRemoteTopButton(), null);
- topPanel.setBackground(java.awt.Color.lightGray);
- */
-+//System.out.println("getTopPanel");
- }
- return topPanel;
- }
-@@ -348,6 +509,7 @@
- statusPanel.add(getJProgressBar(), null);
- statusPanel.add(getConnectionStatus(), null);
- statusPanel.setBackground(java.awt.Color.lightGray);
-+//System.out.println("getStatusPanel");
-
- }
- return statusPanel;
-@@ -368,6 +530,7 @@
- remotePanel.add(getRemoteScrollPane(), null);
- remotePanel.add(getRemoteStatus(), null);
- remotePanel.setBackground(java.awt.Color.lightGray);
-+//System.out.println("getRemotePanel");
- }
- return remotePanel;
- }
-@@ -390,6 +553,7 @@
- localPanel.setComponentOrientation(
- java.awt.ComponentOrientation.UNKNOWN);
- localPanel.setName("localPanel");
-+//System.out.println("getLocalPanel");
- }
- return localPanel;
- }
-@@ -405,12 +569,15 @@
- buttonPanel = new javax.swing.JPanel();
- buttonPanel.setLayout(null);
- buttonPanel.add(getReceiveButton(), null);
-+ buttonPanel.add(getRefreshButton(), null); // runge/x11vnc
-+ buttonPanel.add(getViewButton(), null); // runge/x11vnc
- buttonPanel.add(getNewFolderButton(), null);
- buttonPanel.add(getCloseButton(), null);
- buttonPanel.add(getDeleteButton(), null);
- buttonPanel.add(getSendButton(), null);
- buttonPanel.add(getStopButton(), null);
- buttonPanel.setBackground(java.awt.Color.lightGray);
-+//System.out.println("getButtonPanel");
- }
- return buttonPanel;
- }
-@@ -422,10 +589,11 @@
- private javax.swing.JButton getSendButton() {
- if (sendButton == null) {
- sendButton = new javax.swing.JButton();
-- sendButton.setBounds(20, 30, 97, 25);
-+ sendButton.setBounds(15, 30, 107, 25); // runge/x11vnc
- sendButton.setText("Send >>");
- sendButton.setName("sendButton");
- sendButton.addActionListener(this);
-+//System.out.println("getSendButton");
-
- }
- return sendButton;
-@@ -438,7 +606,7 @@
- private javax.swing.JButton getReceiveButton() {
- if (receiveButton == null) {
- receiveButton = new javax.swing.JButton();
-- receiveButton.setBounds(20, 60, 97, 25);
-+ receiveButton.setBounds(15, 60, 107, 25); // runge/x11vnc
- receiveButton.setText("<< Receive");
- receiveButton.setName("receiveButton");
- receiveButton.addActionListener(this);
-@@ -453,7 +621,7 @@
- private javax.swing.JButton getDeleteButton() {
- if (deleteButton == null) {
- deleteButton = new javax.swing.JButton();
-- deleteButton.setBounds(20, 110, 97, 25);
-+ deleteButton.setBounds(15, 110, 107, 25); // runge/x11vnc
- deleteButton.setText("Delete File");
- deleteButton.setName("deleteButton");
- deleteButton.addActionListener(this);
-@@ -468,7 +636,7 @@
- private javax.swing.JButton getNewFolderButton() {
- if (newFolderButton == null) {
- newFolderButton = new javax.swing.JButton();
-- newFolderButton.setBounds(20, 140, 97, 25);
-+ newFolderButton.setBounds(15, 140, 107, 25); // runge/x11vnc
- newFolderButton.setText("New Folder");
- newFolderButton.setName("newFolderButton");
- newFolderButton.addActionListener(this);
-@@ -476,6 +644,39 @@
- return newFolderButton;
- }
-
-+// begin runge/x11vnc
-+ /**
-+ * This method initializes refreshButton
-+ *
-+ * @return javax.swing.JButton
-+ */
-+ private javax.swing.JButton getRefreshButton() {
-+ if (refreshButton == null) {
-+ refreshButton = new javax.swing.JButton();
-+ refreshButton.setBounds(15, 170, 107, 25);
-+ refreshButton.setText("Refresh");
-+ refreshButton.setName("refreshButton");
-+ refreshButton.addActionListener(this);
-+ }
-+ return refreshButton;
-+ }
-+ /**
-+ * This method initializes viewButton
-+ *
-+ * @return javax.swing.JButton
-+ */
-+ private javax.swing.JButton getViewButton() {
-+ if (viewButton == null) {
-+ viewButton = new javax.swing.JButton();
-+ viewButton.setBounds(15, 200, 107, 25);
-+ viewButton.setText("View File");
-+ viewButton.setName("viewButton");
-+ viewButton.addActionListener(this);
-+ }
-+ return viewButton;
-+ }
-+// end runge/x11vnc
-+
- /**
- * This method initializes stopButton
- *
-@@ -486,7 +687,7 @@
- if (stopButton == null)
- {
- stopButton = new javax.swing.JButton();
-- stopButton.setBounds(20, 200, 97, 25);
-+ stopButton.setBounds(15, 230, 107, 25); // runge/x11vnc
- stopButton.setText("Stop");
- stopButton.setName("stopButton");
- stopButton.addActionListener(this);
-@@ -503,8 +704,12 @@
- private javax.swing.JButton getCloseButton() {
- if (closeButton == null) {
- closeButton = new javax.swing.JButton();
-- closeButton.setBounds(20, 325, 97, 25);
-- closeButton.setText("Close");
-+ closeButton.setBounds(15, 325, 107, 25); // runge/x11vnc
-+ if (viewer.ftpOnly) {
-+ closeButton.setText("Quit");
-+ } else {
-+ closeButton.setText("Close");
-+ }
- closeButton.setName("closeButton");
- closeButton.addActionListener(this);
- }
-@@ -551,6 +756,7 @@
- //Select the second entry (e.g. C:\)
- // localDrivesComboBox.setSelectedIndex(1);
- localDrivesComboBox.addActionListener(this);
-+//System.out.println("getLocalDrivesComboBox");
- }
- updateDriveList = false;
- return localDrivesComboBox;
-@@ -567,6 +773,7 @@
- remoteDrivesComboBox.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
- remoteDrivesComboBox.addActionListener(this);
-+//System.out.println("getRemoteDrivesComboBox");
-
- }
- return remoteDrivesComboBox;
-@@ -587,6 +794,7 @@
- localMachineLabel.setFont(
- new java.awt.Font("Dialog", java.awt.Font.BOLD, 11));
- localMachineLabel.setEditable(false);
-+//System.out.println("getLocalMachineLabel");
- }
- return localMachineLabel;
- }
-@@ -622,6 +830,7 @@
- localTopButton.setFont(
- new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
- localTopButton.addActionListener(this);
-+//System.out.println("getLocalTopButton");
- }
- return localTopButton;
- }
-@@ -638,6 +847,7 @@
- remoteTopButton.setFont(
- new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
- remoteTopButton.addActionListener(this);
-+//System.out.println("getRemoteTopButton");
- }
- return remoteTopButton;
- }
-@@ -650,9 +860,24 @@
- private javax.swing.JList getLocalFileTable() {
- if (localFileTable == null) {
- localList = new Vector(0);
-+ localListInfo = new Vector(0);
- localFileTable = new JList(localList);
-+ MouseMotionListener mlisten = new MouseMotionAdapter() {
-+ public void mouseMoved(MouseEvent e) {
-+ int index = localFileTable.locationToIndex(e.getPoint());
-+ if (index == lastLocalIndex) {
-+ return;
-+ } else if (index < 0) {
-+ return;
-+ }
-+ lastLocalIndex = index;
-+ connectionStatus.setText((String) localListInfo.get(index));
-+ }
-+ };
- localFileTable.addMouseListener(this);
-+ localFileTable.addMouseMotionListener(mlisten);
- localFileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-+//System.out.println("getLocalFileTable");
- }
- return localFileTable;
- }
-@@ -669,6 +894,7 @@
- localScrollPane.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
- localScrollPane.setName("localFileList");
-+//System.out.println("getLocalScrollPane");
- }
- return localScrollPane;
- }
-@@ -680,10 +906,25 @@
- private javax.swing.JList getRemoteFileTable() {
- if (remoteFileTable == null) {
- remoteList = new Vector(0);
-+ remoteListInfo = new Vector(0);
- remoteFileTable = new JList(remoteList);
-+ MouseMotionListener mlisten = new MouseMotionAdapter() {
-+ public void mouseMoved(MouseEvent e) {
-+ int index = remoteFileTable.locationToIndex(e.getPoint());
-+ if (index == lastRemoteIndex) {
-+ return;
-+ } else if (index < 0) {
-+ return;
-+ }
-+ lastRemoteIndex = index;
-+ connectionStatus.setText((String) remoteListInfo.get(index));
-+ }
-+ };
- remoteFileTable.addMouseListener(this);
-+ remoteFileTable.addMouseMotionListener(mlisten);
- remoteFileTable.setSelectedValue("C:\\", false);
- remoteFileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-+//System.out.println("getRemoteFileTable");
-
- }
- return remoteFileTable;
-@@ -698,6 +939,7 @@
- remoteScrollPane = new javax.swing.JScrollPane();
- remoteScrollPane.setViewportView(getRemoteFileTable());
- remoteScrollPane.setPreferredSize(new java.awt.Dimension(325, 418));
-+//System.out.println("getRemoteScrollPane");
- }
- return remoteScrollPane;
- }
-@@ -716,6 +958,7 @@
- remoteLocation.setBackground(new Color(255,255,238));
- remoteLocation.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
-+//System.out.println("getRemoteLocation");
- }
- return remoteLocation;
- }
-@@ -732,6 +975,7 @@
- localLocation.setBackground( new Color(255,255,238));
- localLocation.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
-+//System.out.println("getLocalLocation");
- }
- return localLocation;
- }
-@@ -748,6 +992,7 @@
- localStatus.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
- localStatus.setEditable(false);
-+//System.out.println("getLocalStatus");
- }
- return localStatus;
- }
-@@ -764,6 +1009,7 @@
- remoteStatus.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
- remoteStatus.setEditable(false);
-+//System.out.println("getRemoteStatus");
- }
- return remoteStatus;
- }
-@@ -777,9 +1023,10 @@
- historyComboBox = new javax.swing.JComboBox();
- historyComboBox.setFont(
- new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
-- historyComboBox.insertItemAt(new String("Pulldown to view history ..."),0);
-+ historyComboBox.insertItemAt(new String("Pulldown to view history; Press Escape to Close/Quit; Press Ctrl-R to Reset Panel."),0);
- historyComboBox.setSelectedIndex(0);
- historyComboBox.addActionListener(this);
-+//System.out.println("getHistoryComboBox");
- }
- return historyComboBox;
- }
-@@ -791,6 +1038,7 @@
- private javax.swing.JProgressBar getJProgressBar() {
- if (jProgressBar == null) {
- jProgressBar = new javax.swing.JProgressBar();
-+//System.out.println("getJProgressBar");
- }
- return jProgressBar;
- }
-@@ -806,6 +1054,7 @@
- connectionStatus.setBackground(java.awt.Color.lightGray);
- connectionStatus.setFont(
- new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
-+//System.out.println("getConnectionStatus");
- }
- connectionStatus.setEditable(false);
- return connectionStatus;
-@@ -815,7 +1064,12 @@
- * Implements Action listener.
- */
- public void actionPerformed(ActionEvent evt) {
-- System.out.println(evt.getSource());
-+// System.out.println(evt.getSource());
-+
-+ if (ignore_events) {
-+ System.out.println("ignore_events: " + evt.getSource());
-+ return;
-+ }
-
- if (evt.getSource() == closeButton)
- { // Close Button
-@@ -829,15 +1083,27 @@
- {
- doReceive();
- }
-+// begin runge/x11vnc
-+ else if (evt.getSource() == viewButton)
-+ {
-+ doView();
-+ }
-+// end runge/x11vnc
- else if (evt.getSource() == localDrivesComboBox)
- {
- changeLocalDrive();
- }
- else if (evt.getSource() == remoteDrivesComboBox)
- {
-+//System.out.println("remoteDrivesComboBox"); // runge/x11vnc
- changeRemoteDrive();
-- remoteList.clear();
-- remoteFileTable.setListData(remoteList);
-+
-+ // are these really needed? changeRemoteDrive() does them at the end.
-+ if (false) {
-+ remoteList.clear();
-+ remoteListInfo.clear();
-+ remoteFileTable.setListData(remoteList);
-+ }
- }
- else if (evt.getSource() == localTopButton)
- {
-@@ -845,12 +1111,17 @@
- }
- else if (evt.getSource() == remoteTopButton)
- {
-+//System.out.println("remoteTopButton"); // runge/x11vnc
- changeRemoteDrive();
- }
- else if(evt.getSource() == deleteButton)
- {
- doDelete();
- }
-+ else if(evt.getSource() == refreshButton)
-+ {
-+ doRefresh();
-+ }
- else if(evt.getSource()==newFolderButton)
- {
- doNewFolder();
-@@ -864,7 +1135,7 @@
-
- private void doNewFolder()
- {
-- String name = JOptionPane.showInputDialog(null,"Enter new directory name", "Create New Directory", JOptionPane.QUESTION_MESSAGE);
-+ String name = JOptionPane.showInputDialog(jContentPane,"Enter new directory name", "Create New Directory", JOptionPane.QUESTION_MESSAGE);
- if(selectedTable.equals("remote"))
- {
- name = remoteLocation.getText()+name;
-@@ -880,34 +1151,106 @@
- historyComboBox.setSelectedIndex(0);
- }
- }
-- private void doClose()
-+ public void doClose()
- {
-+ if (viewer.ftpOnly) {
-+ viewer.disconnect();
-+ return;
-+ }
- try {
- this.setVisible(false);
-- viewer.rfb.writeFramebufferUpdateRequest(
-- 0,
-- 0,
-- viewer.rfb.framebufferWidth,
-- viewer.rfb.framebufferHeight,
-- true);
-+ viewer.rfb.writeFramebufferUpdateRequest(0, 0, viewer.rfb.framebufferWidth,
-+ viewer.rfb.framebufferHeight, true);
-+
-+ if (false) {
-+ this.dispose();
-+ jContentPane = null;
-+ }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-+ private void unSwing() {
-+ jContentPane = null;
-+ topPanel = null;
-+ topPanelLocal = null;
-+ topPanelRemote = null;
-+ topPanelCenter = null;
-+ statusPanel = null;
-+ remotePanel = null;
-+ localPanel = null;
-+ buttonPanel = null;
-+ sendButton = null;
-+ receiveButton = null;
-+ deleteButton = null;
-+ newFolderButton = null;
-+ stopButton = null;
-+ closeButton = null;
-+ dummyButton = null;
-+ localDrivesComboBox = null;
-+ remoteDrivesComboBox = null;
-+ localMachineLabel = null;
-+ remoteMachineLabel = null;
-+ localTopButton = null;
-+ remoteTopButton = null;
-+ localScrollPane = null;
-+ localFileTable = null;
-+ remoteScrollPane = null;
-+ remoteFileTable = null;
-+ remoteLocation = null;
-+ localLocation = null;
-+ localStatus = null;
-+ remoteStatus = null;
-+ historyComboBox = null;
-+ jProgressBar = null;
-+ connectionStatus = null;
-+ viewButton = null;
-+ refreshButton = null;
-+ }
-+
-+ public void doReset()
-+ {
-+ try {
-+ this.setVisible(false);
-+ this.dispose();
-+ jContentPane = null;
-+ try {Thread.sleep(500);} catch (InterruptedException e) {}
-+ viewer.ftp_init();
-+ } catch (Exception e) {
-+ // TODO Auto-generated catch block
-+ e.printStackTrace();
-+ }
-+ }
-
-+ public void doOpen()
-+ {
-+ try {
-+ this.setVisible(true);
-+ if (false) {
-+ this.initialize();
-+ }
-+ } catch (Exception e) {
-+ // TODO Auto-generated catch block
-+ e.printStackTrace();
-+ }
-+ }
- private void doDelete()
- {
-- System.out.println("Delete Button Pressed");
-+// System.out.println("Delete Button Pressed");
- //Call this method to delete a file at server
- if(selectedTable.equals("remote"))
- {
-- String sFileName = ((String) this.remoteFileTable.getSelectedValue());
-+ Object selected = this.remoteFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return;
-+ }
-+ String sFileName = ((String) selected);
-
- // sf@2004 - Directory can't be deleted
- if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
- {
-- JOptionPane.showMessageDialog(null, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
-+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
- return;
- }
-
-@@ -916,7 +1259,7 @@
- // sf@2004 - Delete prompt
- if (remoteList.contains(sFileName))
- {
-- int r = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Remote Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
-+ int r = JOptionPane.showConfirmDialog(jContentPane, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Remote Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
- if (r == JOptionPane.NO_OPTION)
- return;
- }
-@@ -926,18 +1269,22 @@
- }
- else
- {
-- String sFileName = ((String) this.localFileTable.getSelectedValue());
-+ Object selected = this.localFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return;
-+ }
-+ String sFileName = ((String) selected);
-
- // sf@2004 - Directory can't be deleted
- if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
- {
-- JOptionPane.showMessageDialog(null, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
-+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
- return;
- }
- // sf@2004 - Delete prompt
- if (localList.contains(sFileName))
- {
-- int r = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Local Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
-+ int r = JOptionPane.showConfirmDialog(jContentPane, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Local Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
- if (r == JOptionPane.NO_OPTION)
- return;
- }
-@@ -952,21 +1299,25 @@
-
- private void doReceive()
- {
-- System.out.println("Received Button Pressed");
-+// System.out.println("Received Button Pressed");
-
-- String sFileName = ((String) this.remoteFileTable.getSelectedValue());
-+ Object selected = this.remoteFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return;
-+ }
-+ String sFileName = ((String) selected);
-
- // sf@2004 - Directory can't be transfered
- if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
- {
-- JOptionPane.showMessageDialog(null, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
-+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
- return;
- }
-
- // sf@2004 - Overwrite prompt
- if (localList.contains(sFileName))
- {
-- int r = JOptionPane.showConfirmDialog(null, "The file < " + sFileName + " >\n already exists on Local Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
-+ int r = JOptionPane.showConfirmDialog(jContentPane, "The file < " + sFileName + " >\n already exists on Local Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
- if (r == JOptionPane.NO_OPTION)
- return;
- }
-@@ -979,23 +1330,101 @@
- viewer.rfb.requestRemoteFile(remoteFileName,localDestinationPath);
- }
-
-+// begin runge/x11vnc
-+ private void doRefresh()
-+ {
-+ System.out.println("Refreshing Local and Remote.");
-+ refreshLocalLocation();
-+ refreshRemoteLocation();
-+ }
-+
-+ private void doView()
-+ {
-+// System.out.println("View Button Pressed");
-+
-+ if (selectedTable == null) {
-+ return;
-+ }
-+ if (selectedTable.equals("remote")) {
-+ viewRemote();
-+ } else if (selectedTable.equals("local")) {
-+ viewLocal();
-+ }
-+ }
-+
-+ private File doReceiveTmp()
-+ {
-+
-+ if (remoteFileTable == null) {
-+ return null;
-+ }
-+ Object selected = this.remoteFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return null;
-+ }
-+ String sFileName = ((String) selected);
-+
-+ if (sFileName == null) {
-+ return null;
-+ }
-+
-+ // sf@2004 - Directory can't be transfered
-+ if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
-+ {
-+ return null;
-+ }
-+
-+ File tmp = null;
-+ try {
-+ tmp = File.createTempFile("ULTRAFTP", ".txt");
-+ } catch (Exception e) {
-+ return null;
-+ }
-+
-+ //updateHistory("Downloaded " + localSelection.toString());
-+ String remoteFileName = this.remoteLocation.getText();
-+ remoteFileName+= ((String) this.remoteFileTable.getSelectedValue()).substring(1);
-+ System.out.println("remoteFileName: " + remoteFileName);
-+if (false) {
-+ char[] b = remoteFileName.toCharArray();
-+ for (int n = 0; n < b.length; n++) {
-+ System.out.print(Integer.toHexString(b[n]) + " ");
-+ }
-+ System.out.println("");
-+ for (int n = 0; n < b.length; n++) {
-+ System.out.print(b[n]);
-+ }
-+ System.out.println("");
-+}
-+
-+ String localDestinationPath = tmp.getAbsolutePath();
-+ viewer.rfb.requestRemoteFile(remoteFileName,localDestinationPath);
-+ System.out.println("ReceiveTmp: " + localDestinationPath);
-+ return tmp;
-+ }
-+// end runge/x11vnc
-+
- private void doSend()
- {
-- System.out.println("Send Button Pressed");
-+// System.out.println("Send Button Pressed");
-
-- String sFileName = ((String) this.localFileTable.getSelectedValue());
-+ Object selected = this.localFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return;
-+ }
-+ String sFileName = ((String) selected);
-
- // sf@2004 - Directory can't be transfered
- if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
- {
-- JOptionPane.showMessageDialog(null, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
-+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
- return;
- }
-
- // sf@2004 - Overwrite prompt
- if (remoteList.contains(sFileName))
- {
-- int r = JOptionPane.showConfirmDialog(null, "The file < " + sFileName + " >\n already exists on Remote Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
-+ int r = JOptionPane.showConfirmDialog(jContentPane, "The file < " + sFileName + " >\n already exists on Remote Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
- if (r == JOptionPane.NO_OPTION)
- return;
- }
-@@ -1013,6 +1442,7 @@
- //
- private void doStop()
- {
-+ System.out.println("** Current Transfer Aborted **");
- viewer.rfb.fAbort = true;
- }
- /**
-@@ -1024,6 +1454,14 @@
- System.out.println("History: " + message);
- historyComboBox.insertItemAt(new String(message), 0);
- }
-+
-+ public void receivedRemoteDirectoryName(String str) {
-+ if (doingShortcutDir) {
-+ if (str.length() > 1) {
-+ remoteLocation.setText(str);
-+ }
-+ }
-+ }
-
- /**
- * This method updates the file table to the current selection of the remoteComboBox
-@@ -1034,11 +1472,44 @@
- remoteSelection = null;
-
- if (!updateDriveList) {
-- String drive = remoteDrivesComboBox.getSelectedItem().toString().substring(0,1)+ ":\\";
-- viewer.rfb.readServerDirectory(drive);
-- remoteLocation.setText(drive);
-+//System.out.println("changeRemoteDrive-A " + drive); // begin runge/x11vnc
-+ Object selected = remoteDrivesComboBox.getSelectedItem();
-+ if (selected != null) {
-+ String instr = selected.toString();
-+ if (instr != null) {
-+System.out.println("changeRemoteDrive: instr='" + instr + "'");
-+ String drive = instr.substring(0,1)+ ":\\";
-+ if (instr.startsWith(" [")) {
-+ int idx = instr.lastIndexOf(']');
-+ if (idx > 2) {
-+ drive = instr.substring(2, idx);
-+ } else {
-+ drive = instr.substring(2);
-+ }
-+ if (drive.equals("Home")) {
-+ drive = "";
-+ }
-+ drive += "\\";
-+ doingShortcutDir = true;
-+ } else {
-+ doingShortcutDir = false;
-+ drive = saveRemoteHack(drive);
-+ }
-+ gotShortcutDir = false;
-+ viewer.rfb.readServerDirectory(drive);
-+ if (!gotShortcutDir) {
-+ remoteLocation.setText(drive);
-+ }
-+ } else {
-+System.out.println("changeRemoteDrive: instr null");
-+ }
-+ } else {
-+System.out.println("changeRemoteDrive: selection null");
-+ }
-+//System.out.println("changeRemoteDrive-B " + drive); // end runge/x11vnc
- }
- remoteList.clear();
-+ remoteListInfo.clear();
- remoteFileTable.setListData(remoteList);
- }
- /**
-@@ -1048,6 +1519,7 @@
- private void changeLocalDrive()
- {
- File currentDrive = new File(localDrivesComboBox.getSelectedItem().toString());
-+System.out.println("changeLocalDrive " + currentDrive.toString()); // runge/x11vnc
- if(currentDrive.canRead())
- {
- localSelection = null;
-@@ -1057,9 +1529,11 @@
- else
- {
- localList.clear();
-+ localListInfo.clear();
- localStatus.setText("WARNING: Drive " + localDrivesComboBox.getSelectedItem().toString());
- connectionStatus.setText(" > WARNING - Local Drive unavailable (possibly restricted access or media not present)");
- }
-+
- }
- /**
- * Determines which FileTable was double-clicked and updates the table
-@@ -1098,10 +1572,18 @@
- selectedTable = "remote";
- localFileTable.setBackground(new Color(238, 238, 238));
- remoteFileTable.setBackground(new Color(255, 255, 255));
-- String name = (remoteFileTable.getSelectedValue().toString()).substring(1);
-+ Object selected = remoteFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return;
-+ }
-+ String selstr = selected.toString();
-+ if (selstr == null) {
-+ return;
-+ }
-+ String name = selstr.substring(1);
- if( !name.substring(0, 2).equals(" ["))
- remoteSelection = remoteLocation.getText() + name.substring(0, name.length());
--
-+
- }
-
- /*
-@@ -1115,10 +1597,38 @@
- localFileTable.setBackground(new Color(255, 255, 255));
- File currentSelection = new File(currentLocalDirectory, getTrimmedSelection());
-
-- if(currentSelection.isFile())
-+// begin runge/x11vnc
-+ // localSelection = currentSelection.getAbsoluteFile();
-+ if(currentSelection.isFile()) {
- localSelection = currentSelection.getAbsoluteFile();
-+ localCurrentIsDir = false;
-+ } else {
-+ localCurrentIsDir = true;
-+ }
-+// end runge/x11vnc
-
- }
-+
-+// begin runge/x11vnc
-+ private void viewRemote() {
-+ File tmp = doReceiveTmp();
-+ if (tmp == null) {
-+ return;
-+ }
-+ TextViewer tv = new TextViewer("Remote: " + remoteSelection, tmp, true);
-+ }
-+ private void viewLocal() {
-+ if (localSelection == null) {
-+ return;
-+ }
-+ if (localCurrentIsDir) {
-+ return;
-+ }
-+ File loc = new File(localSelection.toString());
-+ TextViewer tv = new TextViewer("Local: " + localSelection.toString(), loc, false);
-+ }
-+// end runge/x11vnc
-+
- /**
- * Updates the Remote File Table based on selection. Called from mouseClicked handler
- */
-@@ -1126,20 +1636,29 @@
- String name = null;
- String action = null;
- String drive = null;
-- name = (remoteFileTable.getSelectedValue().toString()).substring(1);
-+ Object selected = remoteFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return;
-+ }
-+ String sname = selected.toString();
-+ if (sname == null) {
-+ return;
-+ }
-+ name = sname.substring(1);
-
- if (name.equals("[..]"))
- {
- action = "up";
- remoteSelection = null;
- drive = remoteLocation.getText().substring(0, remoteLocation.getText().length() - 1);
-- // JOptionPane.showMessageDialog(null, (String)drive, "FileTransfer DEBUG", JOptionPane.INFORMATION_MESSAGE);
-+ // JOptionPane.showMessageDialog(jContentPane, (String)drive, "FileTransfer DEBUG", JOptionPane.INFORMATION_MESSAGE);
- int index = drive.lastIndexOf("\\");
- drive = drive.substring(0, index + 1);
-
- remoteLocation.setText(drive);
- viewer.rfb.readServerDirectory(drive);
- remoteList.clear();
-+ remoteListInfo.clear();
- remoteFileTable.setListData(remoteList);
- }
- else if (!name.substring(0, 2).equals(" [") && !name.substring((name.length() - 1), name.length()).equals("]"))
-@@ -1149,6 +1668,7 @@
- remoteSelection = remoteLocation.getText() + name.substring(0, name.length());
- drive = remoteLocation.getText();
- // ??
-+ viewRemote(); // runge/x11vnc
- }
- else
- {
-@@ -1159,10 +1679,12 @@
- remoteLocation.setText(drive);
- viewer.rfb.readServerDirectory(drive);
- remoteList.clear();
-+ remoteListInfo.clear();
- remoteFileTable.setListData(remoteList);
- }
- //remoteLocation.setText(drive);
- }
-+
- /**
- * Updates the Local File Table based on selection. Called from MouseClicked handler
- */
-@@ -1188,6 +1710,7 @@
- else if (currentSelection.isFile())
- {
- localSelection = currentSelection.getAbsoluteFile();
-+ viewLocal(); // runge/x11vnc
- }
- else if (currentSelection.isDirectory())
- {
-@@ -1201,13 +1724,22 @@
- *
- */
- private String getTrimmedSelection(){
-- String currentSelection = (localFileTable.getSelectedValue().toString()).substring(1);
-- if(currentSelection.substring(0,1).equals("[") &&
-- currentSelection.substring(currentSelection.length()-1,currentSelection.length()).equals("]")){
-- return currentSelection.substring(1,currentSelection.length()-1);
-- } else {
-- return currentSelection;
-- }
-+ String currentSelection = "";
-+ Object selected = localFileTable.getSelectedValue();
-+ if (selected == null) {
-+ return currentSelection;
-+ }
-+ String selstr = selected.toString();
-+ if (selstr == null) {
-+ return currentSelection;
-+ }
-+ currentSelection = selstr.substring(1);
-+ if(currentSelection.substring(0,1).equals("[") &&
-+ currentSelection.substring(currentSelection.length()-1,currentSelection.length()).equals("]")){
-+ return currentSelection.substring(1,currentSelection.length()-1);
-+ } else {
-+ return currentSelection;
-+ }
- }
-
- /*
-@@ -1241,36 +1773,148 @@
- return null;
- }
-
-+ String timeStr(long t) {
-+ Date date = new Date(t);
-+ return date.toString();
-+ }
-+ String dotPast(double f, int n) {
-+ String fs = "" + f;
-+ int i = fs.lastIndexOf(".") + n;
-+ if (i >= 0) {
-+ int len = fs.length();
-+ if (i >= len) {
-+ i = len-1;
-+ }
-+ fs = fs.substring(0, i);
-+ }
-+ return fs;
-+ }
-+ String sizeStr(int s) {
-+ if (s < 0) {
-+ return s + "? B";
-+ } else if (s < 1024) {
-+ return s + " B";
-+ } else if (s < 1024 * 1024) {
-+ double k = s / 1024.0;
-+ String ks = dotPast(k, 3);
-+
-+ return s + " (" + ks + " KB)";
-+ } else {
-+ double m = s / (1024.0*1024.0);
-+ String ms = dotPast(m, 3);
-+ return s + " (" + ms + " MB)";
-+ }
-+ }
-+
-+ int max_char(String text) {
-+ int maxc = 0;
-+ char chars[] = text.toCharArray();
-+ for (int n = 0; n < chars.length; n++) {
-+ if ((int) chars[n] > maxc) {
-+ maxc = (int) chars[n];
-+ }
-+ }
-+ return maxc;
-+ }
-
- /*
- * Navigates the local file structure up or down one directory
- */
- public void changeLocalDirectory(File dir)
- {
-- currentLocalDirectory = dir; // Updates Global
-+ dir = saveLocalHack(dir); // runge/x11vnc
-+
-+ if (dir == null) {
-+ connectionStatus.setText("Error changing local directory.");
-+ historyComboBox.insertItemAt(new String("> Error changing local directory."), 0);
-+ historyComboBox.setSelectedIndex(0);
-+ return;
-+ }
-+
- File allFiles[] = dir.listFiles(); // Reads files
- String[] contents = dir.list();
-
-+ if (contents == null || allFiles == null) {
-+ connectionStatus.setText("Error changing local directory.");
-+ historyComboBox.insertItemAt(new String("> Error changing local directory."), 0);
-+ historyComboBox.setSelectedIndex(0);
-+ return;
-+ }
-+
-+ currentLocalDirectory = dir; // Updates Global
-+// begin runge/x11vnc
-+System.out.println("changeLocalDirectory: " + dir.toString());
-+ if (contents != null) {
-+ java.util.Arrays.sort(contents, String.CASE_INSENSITIVE_ORDER);
-+ for (int i = 0; i < contents.length; i++) {
-+ allFiles[i] = new File(dir, contents[i]);
-+ }
-+ } else {
-+ return;
-+ }
-+// end runge/x11vnc
-+
- localList.clear();
-+ localListInfo.clear();
- localList.addElement(" [..]");
-+ localListInfo.addElement(" [..]");
-+
-+ ArrayList DirInfo = new ArrayList();
-+ ArrayList FilInfo = new ArrayList();
-+
-+ Charset charset = Charset.forName("ISO-8859-1");
-+ CharsetDecoder decoder = charset.newDecoder();
-+ CharsetEncoder encoder = charset.newEncoder();
-
- // Populate the Lists
- for (int i = 0; i < contents.length; i++)
- {
-- if (allFiles[i].isDirectory())
-+ String f1 = contents[i];
-+
-+if (false) {
-+
-+System.out.println("max_char: " + max_char(f1) + " " + f1);
-+ if (max_char(f1) > 255) {
-+ try {
-+System.out.println("bbuf1");
-+ ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(f1.toCharArray()));
-+System.out.println("bbuf2");
-+ CharBuffer cbuf = decoder.decode(bbuf);
-+System.out.println("bbuf3");
-+ f1 = cbuf.toString();
-+System.out.println("did bbuf: " + f1);
-+ } catch (Exception e) {
-+ ;
-+ }
-+ }
-+}
-+
-+ String f2 = f1;
-+ if (f2.length() < 24) {
-+ for (int ik = f2.length(); ik < 24; ik++) {
-+ f2 = f2 + " ";
-+ }
-+ }
-+ String s = f2 + " \tLastmod: " + timeStr(allFiles[i].lastModified()) + " \t\tSize: " + sizeStr((int) allFiles[i].length());
-+ if (allFiles[i].isDirectory()) {
- // localList.addElement("[" + contents[i] + "]");
-- DirsList.add(" [" + contents[i] + "]"); // sf@2004
-- else
-- {
-+ DirsList.add(" [" + f1 + "]"); // sf@2004
-+ DirInfo.add(s);
-+ } else {
- // localList.addElement(contents[i]);
-- FilesList.add(" " + contents[i]); // sf@2004
-+ FilesList.add(" " + f1); // sf@2004
-+ FilInfo.add(s);
- }
- }
- // sf@2004
-- for (int i = 0; i < DirsList.size(); i++)
-+ for (int i = 0; i < DirsList.size(); i++) {
- localList.addElement(DirsList.get(i));
-- for (int i = 0; i < FilesList.size(); i++)
-+ localListInfo.addElement(DirInfo.get(i));
-+ }
-+ for (int i = 0; i < FilesList.size(); i++) {
- localList.addElement(FilesList.get(i));
-+ localListInfo.addElement(FilInfo.get(i));
-+ }
-
- FilesList.clear();
- DirsList.clear();
-@@ -1296,3 +1940,147 @@
- }
-
- } // @jve:visual-info decl-index=0 visual-constraint="10,10"
-+
-+// begin runge/x11vnc
-+class TextViewer extends JFrame implements ActionListener {
-+
-+ JTextArea textArea = new JTextArea(35, 80);
-+ File file = null;
-+ JButton refreshButton;
-+ JButton dismissButton;
-+ Timer tim = null;
-+ int rcnt = 0;
-+ int tms = 250;
-+ boolean delete_it = false;
-+ TextViewer me;
-+
-+ public TextViewer(String s, File f, boolean d) {
-+
-+ delete_it = d;
-+ file = f;
-+ me = this;
-+
-+ JScrollPane scrollPane = new JScrollPane(textArea,
-+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
-+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
-+
-+ textArea.setEditable(false);
-+ textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
-+
-+ KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, InputEvent.SHIFT_MASK);
-+ AbstractAction escapeAction = new AbstractAction() {
-+ public void actionPerformed(ActionEvent actionEvent) {
-+ cleanse();
-+ me.dispose();
-+ }
-+ };
-+ textArea.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "escapeAction");
-+ textArea.getInputMap().put(stroke, "escapeAction");
-+ textArea.getActionMap().put("escapeAction", escapeAction);
-+
-+ refreshButton = new JButton();
-+ refreshButton.setText("Reload");
-+ refreshButton.setName("refreshButton");
-+ refreshButton.addActionListener(this);
-+
-+ dismissButton = new JButton();
-+ dismissButton.setText("Dismiss");
-+ dismissButton.setName("dismissButton");
-+ dismissButton.addActionListener(this);
-+
-+ JPanel buttons = new JPanel();
-+ buttons.setLayout(new BorderLayout());
-+ buttons.add(refreshButton, BorderLayout.WEST);
-+ buttons.add(dismissButton, BorderLayout.EAST);
-+
-+ JPanel content = new JPanel();
-+ content.setLayout(new BorderLayout());
-+ content.add(scrollPane, BorderLayout.CENTER);
-+ content.add(buttons, BorderLayout.SOUTH);
-+
-+ ActionListener tsk = new ActionListener() {
-+ public void actionPerformed(ActionEvent evt) {
-+ // System.out.println("tsk");
-+ refresh();
-+ }
-+ };
-+ tim = new Timer(tms, tsk);
-+ tim.start();
-+
-+ this.setContentPane(content);
-+ this.setTitle("TextViewer - " + s);
-+ this.pack();
-+ this.setVisible(true);
-+ }
-+
-+ private void refresh() {
-+
-+ rcnt++;
-+ if (rcnt * tms > 3000 && tim != null) {
-+ tim.stop();
-+ tim = null;
-+ }
-+ BufferedReader input = null;
-+ StringBuffer contents = new StringBuffer();
-+ try {
-+ if (input == null) {
-+ input = new BufferedReader(new FileReader(file));
-+ }
-+ String line = null;
-+ int i = 0;
-+ while (( line = input.readLine()) != null) {
-+ if (i == 0) {
-+ // System.out.println("read");
-+ }
-+ i++;
-+ contents.append(line);
-+ contents.append(System.getProperty("line.separator"));
-+ }
-+ } catch (Exception e) {
-+ ;
-+ } finally {
-+ try {
-+ if (input != null) {
-+ input.close();
-+ input = null;
-+ }
-+ } catch (Exception e) {
-+ ;
-+ }
-+ }
-+
-+ textArea.setText(contents.toString());
-+ textArea.setCaretPosition(0);
-+ }
-+
-+ public void actionPerformed(ActionEvent evt) {
-+
-+ if (evt.getSource() == refreshButton) {
-+ refresh();
-+ }
-+ if (evt.getSource() == dismissButton) {
-+ cleanse();
-+ this.dispose();
-+ }
-+ }
-+
-+ private void cleanse() {
-+ if (delete_it && file != null) {
-+ try {
-+ file.delete();
-+ file = null;
-+ } catch (Exception e) {
-+ ;
-+ }
-+ }
-+ }
-+
-+ protected void finalize() throws Throwable {
-+ try {
-+ cleanse();
-+ } finally {
-+ super.finalize();
-+ }
-+ }
-+}
-+// end runge/x11vnc
-diff -Naur JavaViewer.orig/Makefile JavaViewer/Makefile
---- JavaViewer.orig/Makefile 2006-05-29 09:06:32.000000000 -0400
-+++ JavaViewer/Makefile 2010-05-18 20:53:32.000000000 -0400
-@@ -4,6 +4,7 @@
-
- CP = cp
- JC = javac
-+JC_ARGS = -target 1.4 -source 1.4
- JAR = jar
- ARCHIVE = VncViewer.jar
- PAGES = index.vnc shared.vnc noshared.vnc hextile.vnc zlib.vnc tight.vnc
-@@ -20,7 +21,7 @@
- all: $(CLASSES) $(ARCHIVE)
-
- $(CLASSES): $(SOURCES)
-- $(JC) -O $(SOURCES)
-+ $(JC) $(JC_ARGS) -O $(SOURCES)
-
- $(ARCHIVE): $(CLASSES)
- $(JAR) cf $(ARCHIVE) $(CLASSES)
-diff -Naur JavaViewer.orig/OptionsFrame.java JavaViewer/OptionsFrame.java
---- JavaViewer.orig/OptionsFrame.java 2005-11-21 18:50:16.000000000 -0500
-+++ JavaViewer/OptionsFrame.java 2007-05-13 22:18:30.000000000 -0400
-@@ -144,7 +144,10 @@
- choices[jpegQualityIndex].select("6");
- choices[cursorUpdatesIndex].select("Enable");
- choices[useCopyRectIndex].select("Yes");
-- choices[eightBitColorsIndex].select("64");
-+// begin runge/x11vnc
-+// choices[eightBitColorsIndex].select("64");
-+ choices[eightBitColorsIndex].select("Full");
-+// end runge/x11vnc
- choices[mouseButtonIndex].select("Normal");
- choices[viewOnlyIndex].select("No");
- choices[shareDesktopIndex].select("Yes");
-diff -Naur JavaViewer.orig/RfbProto.java JavaViewer/RfbProto.java
---- JavaViewer.orig/RfbProto.java 2006-05-24 15:14:40.000000000 -0400
-+++ JavaViewer/RfbProto.java 2010-11-30 22:13:58.000000000 -0500
-@@ -31,6 +31,7 @@
- import java.net.Socket;
- import java.util.*;
- import java.util.zip.*;
-+import java.text.DateFormat;
-
-
- class RfbProto {
-@@ -86,8 +87,11 @@
-
- // sf@2004 - FileTransfer part
- ArrayList remoteDirsList;
-+ ArrayList remoteDirsListInfo;
- ArrayList remoteFilesList;
-+ ArrayList remoteFilesListInfo;
- ArrayList a;
-+ ArrayList b;
- boolean fFTInit = true; // sf@2004
- boolean fFTAllowed = true;
- boolean fAbort = false;
-@@ -199,6 +203,10 @@
- // playback.
- int numUpdatesInSession;
-
-+// begin runge/x11vnc
-+ int readServerDriveListCnt = -1;
-+ long readServerDriveListTime = 0;
-+// end runge/x11vnc
- //
- // Constructor. Make TCP connection to RFB server.
- //
-@@ -207,7 +215,27 @@
- viewer = v;
- host = h;
- port = p;
-- sock = new Socket(host, port);
-+// begin runge/x11vnc
-+// sock = new Socket(host, port);
-+ if (! viewer.disableSSL) {
-+ System.out.println("new SSLSocketToMe");
-+ SSLSocketToMe ssl;
-+ try {
-+ ssl = new SSLSocketToMe(host, port, v);
-+ } catch (Exception e) {
-+ throw new IOException(e.getMessage());
-+ }
-+
-+ try {
-+ sock = ssl.connectSock();
-+ } catch (Exception es) {
-+ throw new IOException(es.getMessage());
-+ }
-+ } else {
-+ sock = new Socket(host, port);
-+ }
-+// end runge/x11vnc
-+
- is =
- new DataInputStream(
- new BufferedInputStream(sock.getInputStream(), 16384));
-@@ -215,9 +243,12 @@
- osw = new OutputStreamWriter(sock.getOutputStream());
- inDirectory2 = false;
- a = new ArrayList();
-+ b = new ArrayList();
- // sf@2004
- remoteDirsList = new ArrayList();
-+ remoteDirsListInfo = new ArrayList();
- remoteFilesList = new ArrayList();
-+ remoteFilesListInfo = new ArrayList();
-
- sendFileSource = "";
- }
-@@ -420,7 +451,13 @@
- //
-
- int readServerMessageType() throws IOException {
-- int msgType = is.readUnsignedByte();
-+ int msgType;
-+ try {
-+ msgType = is.readUnsignedByte();
-+ } catch (Exception e) {
-+ viewer.disconnect();
-+ return -1;
-+ }
-
- // If the session is being recorded:
- if (rec != null) {
-@@ -600,6 +637,7 @@
- contentParamT = is.readUnsignedByte();
- contentParamT = contentParamT << 8;
- contentParam = contentParam | contentParamT;
-+//System.out.println("FTM: contentType " + contentType + " contentParam " + contentParam);
- if (contentType == rfbRDrivesList || contentType == rfbDirPacket)
- {
- readDriveOrDirectory(contentParam);
-@@ -610,7 +648,7 @@
- }
- else if (contentType == rfbFilePacket)
- {
-- receiveFileChunk();
-+ receiveFileChunk();
- }
- else if (contentType == rfbEndOfFile)
- {
-@@ -618,6 +656,10 @@
- }
- else if (contentType == rfbAbortFileTransfer)
- {
-+ System.out.println("rfbAbortFileTransfer: fFileReceptionRunning="
-+ + fFileReceptionRunning + " fAbort="
-+ + fAbort + " fFileReceptionError="
-+ + fFileReceptionError);
- if (fFileReceptionRunning)
- {
- endOfReceiveFile(false); // Error
-@@ -626,6 +668,11 @@
- {
- // sf@2004 - Todo: Add TestPermission
- // System.out.println("File Transfer Aborted!");
-+
-+ // runge: seems like we must at least read the remaining
-+ // 8 bytes of the header, right?
-+ int size = is.readInt();
-+ int length = is.readInt();
- }
-
- }
-@@ -645,6 +692,7 @@
- {
- System.out.println("ContentType: " + contentType);
- }
-+//System.out.println("FTM: done");
- }
-
- //Refactored from readRfbFileTransferMsg()
-@@ -662,6 +710,7 @@
-
- //Refactored from readRfbFileTransferMsg()
- public void readDriveOrDirectory(int contentParam) throws IOException {
-+//System.out.println("RDOD: " + contentParam + " " + inDirectory2);
- if (contentParam == rfbADrivesList)
- {
- readFTPMsgDriveList();
-@@ -688,13 +737,21 @@
-
- // Internally used. Write an Rfb message to the server
- void writeRfbFileTransferMsg(
-- int contentType,
-- int contentParam,
-- long size, // 0 : compression not supported - 1 : compression supported
-- long length,
-- String text) throws IOException
-+ int contentType,
-+ int contentParam,
-+ long size, // 0 : compression not supported - 1 : compression supported
-+ long length,
-+ String text) throws IOException
- {
- byte b[] = new byte[12];
-+ byte byteArray[];
-+
-+ if (viewer.dsmActive) {
-+ // need to send the rfbFileTransfer msg type twice for the plugin...
-+ byte b2[] = new byte[1];
-+ b2[0] = (byte) rfbFileTransfer;
-+ os.write(b2);
-+ }
-
- b[0] = (byte) rfbFileTransfer;
- b[1] = (byte) contentType;
-@@ -702,7 +759,7 @@
-
- byte by = 0;
- long c = 0;
-- length++;
-+
- c = size & 0xFF000000;
- by = (byte) (c >>> 24);
- b[4] = by;
-@@ -716,6 +773,32 @@
- by = (byte) c;
- b[7] = by;
-
-+ if (text != null) {
-+ byte byteArray0[] = text.getBytes();
-+ int maxc = max_char(text);
-+ if (maxc > 255) {
-+ System.out.println("writeRfbFileTransferMsg: using getBytes(\"UTF-8\")");
-+ byteArray0 = text.getBytes("UTF-8");
-+ } else if (maxc > 127) {
-+ System.out.println("writeRfbFileTransferMsg: using getBytes(\"ISO-8859-1\")");
-+ byteArray0 = text.getBytes("ISO-8859-1");
-+ }
-+ byteArray = new byte[byteArray0.length + 1];
-+ for (int i = 0; i < byteArray0.length; i++) {
-+ byteArray[i] = byteArray0[i];
-+ }
-+ byteArray[byteArray.length - 1] = 0;
-+System.out.println("writeRfbFileTransferMsg: length: " + length + " -> byteArray.length: " + byteArray.length);
-+
-+ // will equal length for ascii, ISO-8859-1, more for UTF-8
-+ length = byteArray.length;
-+
-+ //length++; // used to not include null byte at end.
-+ } else {
-+ String moo = "moo";
-+ byteArray = moo.getBytes();
-+ }
-+
- c = length & 0xFF000000;
- by = (byte) (c >>> 24);
- b[8] = by;
-@@ -729,29 +812,91 @@
- by = (byte) c;
- b[11] = by;
- os.write(b);
-+
-+//System.out.println("size: " + size + " length: " + length + " text: " + text);
-
-
- if (text != null)
- {
-- byte byteArray[] = text.getBytes();
-- byte byteArray2[] = new byte[byteArray.length + 1];
-- for (int i = 0; i < byteArray.length; i++) {
-- byteArray2[i] = byteArray[i];
-+ os.write(byteArray);
-+ }
-+ }
-+
-+ int max_char(String text) {
-+ int maxc = 0;
-+ char chars[] = text.toCharArray();
-+ for (int n = 0; n < chars.length; n++) {
-+ if ((int) chars[n] > maxc) {
-+ maxc = (int) chars[n];
- }
-- byteArray2[byteArray2.length - 1] = 0;
-- os.write(byteArray2);
- }
--
-+ return maxc;
- }
-
-+ String guess_encoding(char[] chars) {
-+ boolean saw_high_char = false;
-+
-+ for (int i = 0; i < chars.length; i++) {
-+ if (chars[i] == '\0') {
-+ break;
-+ }
-+ if (chars[i] >= 128) {
-+ saw_high_char = true;
-+ break;
-+ }
-+ }
-+ if (!saw_high_char) {
-+ return "ASCII";
-+ }
-+ char prev = 1;
-+ boolean valid_utf8 = true;
-+ int n = 0;
-+ for (int i = 0; i < chars.length; i++) {
-+ if (chars[i] == '\0') {
-+ break;
-+ }
-+ char c = chars[i];
-+ if (prev < 128 && c >= 128) {
-+ if (c >> 5 == 0x6) {
-+ n = 1;
-+ } else if (c >> 4 == 0xe) {
-+ n = 2;
-+ } else if (c >> 3 == 0x1e) {
-+ n = 3;
-+ } else if (c >> 2 == 0x3e) {
-+ n = 4;
-+ } else {
-+ valid_utf8 = false;
-+ break;
-+ }
-+ } else {
-+ if (n > 0) {
-+ if (c < 128) {
-+ valid_utf8 = false;
-+ break;
-+ }
-+ n--;
-+ }
-+ }
-+
-+ prev = c;
-+ }
-+ if (valid_utf8) {
-+ return "UTF-8";
-+ } else {
-+ return "ISO-8859-1";
-+ }
-+ }
-+
-+
- //Internally used. Write an rfb message to the server for sending files ONLY
- int writeRfbFileTransferMsgForSendFile(
-- int contentType,
-- int contentParam,
-- long size,
-- long length,
-- String source
-- ) throws IOException
-+ int contentType,
-+ int contentParam,
-+ long size,
-+ long length,
-+ String source
-+ ) throws IOException
- {
- File f = new File(source);
- fis = new FileInputStream(f);
-@@ -768,50 +913,47 @@
-
- while (bytesRead!=-1)
- {
-- counter += bytesRead;
-- myDeflater.setInput(byteBuffer, 0, bytesRead);
-- myDeflater.finish();
-- compressedSize = myDeflater.deflate(CompressionBuffer);
-- myDeflater.reset();
-- // If the compressed data is larger than the original one, we're dealing with
-- // already compressed data
-- if (compressedSize > bytesRead)
-- fCompress = false;
-- this.writeRfbFileTransferMsg(
-- contentType,
-- contentParam,
-- (fCompress ? 1 : 0),
-- (fCompress ? compressedSize-1 : bytesRead-1),
-- null
-- );
-- // Todo: Test write error !
-- os.write(
-- fCompress ? CompressionBuffer : byteBuffer,
-- 0,
-- fCompress ? compressedSize : bytesRead
-- );
--
-- // Todo: test read error !
-- bytesRead = fis.read(byteBuffer);
--
-- // viewer.ftp.connectionStatus.setText("Sent: "+ counter + " bytes of "+ f.length() + " bytes");
-- viewer.ftp.jProgressBar.setValue((int)((counter * 100) / f.length()));
-- viewer.ftp.connectionStatus.setText(">>> Sending File: " + source + " - Size: " + f.length() + " bytes - Progress: " + ((counter * 100) / f.length()) + "%");
--
-- if (fAbort == true)
-- {
-- fAbort = false;
-- fError = true;
-- break;
-- }
-- try
-- {
-- Thread.sleep(5);
-- }
-- catch(InterruptedException e)
-- {
-- System.err.println("Interrupted");
-- }
-+ counter += bytesRead;
-+ myDeflater.setInput(byteBuffer, 0, bytesRead);
-+ myDeflater.finish();
-+ compressedSize = myDeflater.deflate(CompressionBuffer);
-+ myDeflater.reset();
-+ // If the compressed data is larger than the original one, we're dealing with
-+ // already compressed data
-+ if (compressedSize > bytesRead)
-+ fCompress = false;
-+ this.writeRfbFileTransferMsg(
-+ contentType,
-+ contentParam,
-+ (fCompress ? 1 : 0),
-+// RUNGE (fCompress ? compressedSize-1 : bytesRead-1),
-+ (fCompress ? compressedSize : bytesRead),
-+ null
-+ );
-+ // Todo: Test write error !
-+ os.write(fCompress ? CompressionBuffer : byteBuffer, 0, fCompress ? compressedSize : bytesRead);
-+
-+ // Todo: test read error !
-+ bytesRead = fis.read(byteBuffer);
-+
-+ // viewer.ftp.connectionStatus.setText("Sent: "+ counter + " bytes of "+ f.length() + " bytes");
-+ viewer.ftp.jProgressBar.setValue((int)((counter * 100) / f.length()));
-+ viewer.ftp.connectionStatus.setText(">>> Sending File: " + source + " - Size: " + f.length() + " bytes - Progress: " + ((counter * 100) / f.length()) + "%");
-+
-+ if (fAbort == true)
-+ {
-+ fAbort = false;
-+ fError = true;
-+ break;
-+ }
-+ try
-+ {
-+ Thread.sleep(5);
-+ }
-+ catch(InterruptedException e)
-+ {
-+ System.err.println("Interrupted");
-+ }
- }
-
- writeRfbFileTransferMsg(fError ? rfbAbortFileTransfer : rfbEndOfFile, 0, 0, 0, null);
-@@ -831,24 +973,30 @@
- {
- System.out.print((char) is.readUnsignedByte());
- }
-+ System.out.println("");
-+
-+ if (size == rfbRErrorCmd || size == -1) {
-+ viewer.ftp.enableButtons();
-+ viewer.ftp.connectionStatus.setText("Remote file not available for writing.");
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - Remote file not available for writing."), 0);
-+ viewer.ftp.historyComboBox.setSelectedIndex(0);
-+ return;
-+ }
-
-- int ret = writeRfbFileTransferMsgForSendFile(
-- rfbFilePacket,
-- 0,
-- 0,
-- 0,
-- sendFileSource);
-+ int ret = writeRfbFileTransferMsgForSendFile(rfbFilePacket, 0, 0, 0, sendFileSource);
-
- viewer.ftp.refreshRemoteLocation();
- if (ret != 1)
- {
- viewer.ftp.connectionStatus.setText(" > Error - File NOT sent");
-- viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - File: <" + sendFileSource) + "> was not correctly sent (aborted by user or error)",0);
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - File: <" + sendFileSource)
-+ + "> was not correctly sent (aborted or error). Data may still be buffered/in transit. Wait for remote listing...",0);
- }
- else
- {
- viewer.ftp.connectionStatus.setText(" > File sent");
-- viewer.ftp.historyComboBox.insertItemAt(new String(" > File: <" + sendFileSource) + "> was sent to Remote Machine",0);
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > File: <" + sendFileSource)
-+ + "> was sent to Remote Machine. Note: data may still be buffered/in transit. Wait for remote listing...",0);
- }
- viewer.ftp.historyComboBox.setSelectedIndex(0);
- viewer.ftp.enableButtons();
-@@ -907,7 +1055,7 @@
- //Handles acknowledgement that the file has been deleted on the server
- void deleteRemoteFileFeedback() throws IOException
- {
-- is.readInt();
-+ int ret = is.readInt();
- int length = is.readInt();
- String f = "";
- for (int i = 0; i < length; i++)
-@@ -916,7 +1064,11 @@
- }
-
- viewer.ftp.refreshRemoteLocation();
-- viewer.ftp.historyComboBox.insertItemAt(new String(" > Deleted File On Remote Machine: " + f.substring(0, f.length()-1)),0);
-+ if (ret == -1) {
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > ERROR Could not Delete File On Remote Machine: "),0);
-+ } else {
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Deleted File On Remote Machine: " + f.substring(0, f.length()-1)),0);
-+ }
- viewer.ftp.historyComboBox.setSelectedIndex(0);
- }
-
-@@ -926,12 +1078,7 @@
- try
- {
- String temp = text;
-- writeRfbFileTransferMsg(
-- rfbCommand,
-- rfbCFileDelete,
-- 0,
-- temp.length(),
-- temp);
-+ writeRfbFileTransferMsg(rfbCommand, rfbCFileDelete, 0, temp.length(), temp);
- }
- catch (IOException e)
- {
-@@ -943,7 +1090,7 @@
- // Handles acknowledgement that the directory has been created on the server
- void createRemoteDirectoryFeedback() throws IOException
- {
-- is.readInt();
-+ int ret = is.readInt();
- int length = is.readInt();
- String f="";
- for (int i = 0; i < length; i++)
-@@ -951,7 +1098,11 @@
- f += (char)is.readUnsignedByte();
- }
- viewer.ftp.refreshRemoteLocation();
-- viewer.ftp.historyComboBox.insertItemAt(new String(" > Created Directory on Remote Machine: " + f.substring(0, f.length()-1)),0);
-+ if (ret == -1) {
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > ERROR Could not Create Directory on Remote Machine."),0);
-+ } else {
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Created Directory on Remote Machine: " + f.substring(0, f.length()-1)),0);
-+ }
- viewer.ftp.historyComboBox.setSelectedIndex(0);
- }
-
-@@ -961,12 +1112,7 @@
- try
- {
- String temp = text;
-- writeRfbFileTransferMsg(
-- rfbCommand,
-- rfbCDirCreate,
-- 0,
-- temp.length(),
-- temp);
-+ writeRfbFileTransferMsg(rfbCommand, rfbCDirCreate, 0, temp.length(), temp);
- }
- catch (IOException e)
- {
-@@ -979,15 +1125,13 @@
- {
- try
- {
-+//System.out.println("requestRemoteFile text: " + text);
-+//System.out.println("requestRemoteFile leng: " + text.length());
- String temp = text;
- receivePath = localPath;
-
-- writeRfbFileTransferMsg(
-- rfbFileTransferRequest,
-- 0,
-- 1, // 0 : compression not supported - 1 : compression supported
-- temp.length(),
-- temp);
-+ // 0 : compression not supported - 1 : compression supported
-+ writeRfbFileTransferMsg(rfbFileTransferRequest, 0, 1, temp.length(), temp);
- }
- catch (IOException e)
- {
-@@ -1004,6 +1148,9 @@
- viewer.ftp.disableButtons();
- int size = is.readInt();
- int length = is.readInt();
-+
-+//System.out.println("receiveFileHeader size: " + size);
-+//System.out.println("receiveFileHeader leng: " + length);
-
- String tempName = "";
- for (int i = 0; i < length; i++)
-@@ -1011,6 +1158,15 @@
- tempName += (char) is.readUnsignedByte();
- }
-
-+ if (size == rfbRErrorCmd || size == -1) {
-+ fFileReceptionRunning = false;
-+ viewer.ftp.enableButtons();
-+ viewer.ftp.connectionStatus.setText("Remote file not available for reading.");
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - Remote file not available for reading."), 0);
-+ viewer.ftp.historyComboBox.setSelectedIndex(0);
-+ return;
-+ }
-+
- // sf@2004 - Read the high part of file size (not yet in rfbFileTransferMsg for
- // backward compatibility reasons...)
- int sizeH = is.readInt();
-@@ -1021,7 +1177,16 @@
- fileSize=0;
- fileChunkCounter = 0;
- String fileName = receivePath;
-- fos = new FileOutputStream(fileName);
-+ try {
-+ fos = new FileOutputStream(fileName);
-+ } catch (Exception e) {
-+ fFileReceptionRunning = false;
-+ writeRfbFileTransferMsg(rfbAbortFileTransfer, 0, 0, 0, null);
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > ERROR opening Local File: <" + fileName ),0);
-+ viewer.ftp.historyComboBox.setSelectedIndex(0);
-+ viewer.ftp.enableButtons();
-+ return;
-+ }
- writeRfbFileTransferMsg(rfbFileHeader, 0, 0, 0, null);
- }
-
-@@ -1085,7 +1250,13 @@
- fAbort = false;
- fFileReceptionError = true;
- writeRfbFileTransferMsg(rfbAbortFileTransfer, 0, 0, 0, null);
--
-+
-+ //runge for use with x11vnc/libvncserver, no rfbAbortFileTransfer reply sent.
-+ try {Thread.sleep(500);} catch (InterruptedException e) {}
-+ viewer.ftp.enableButtons();
-+ viewer.ftp.refreshLocalLocation();
-+ viewer.ftp.connectionStatus.setText(" > Error - File NOT received");
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - File: <" + receivePath + "> not correctly received from Remote Machine (aborted by user or error)") ,0);
- }
- // sf@2004 - For old FT protocole only
- /*
-@@ -1104,7 +1275,7 @@
- int length = is.readInt();
- fileSize=0;
- fos.close();
--
-+
- viewer.ftp.refreshLocalLocation();
- if (fReceptionOk && !fFileReceptionError)
- {
-@@ -1132,12 +1303,7 @@
- try
- {
- String temp = text;
-- writeRfbFileTransferMsg(
-- rfbDirContentRequest,
-- rfbRDirContent,
-- 0,
-- temp.length(),
-- temp);
-+ writeRfbFileTransferMsg(rfbDirContentRequest, rfbRDirContent, 0, temp.length(), temp);
- }
- catch (IOException e)
- {
-@@ -1197,11 +1363,80 @@
- str += temp;
- }
- }
-+ // runge
-+ viewer.ftp.receivedRemoteDirectoryName(str);
- // viewer.ftp.changeRemoteDirectory(str);
-
- }
- }
-
-+ int zogswap(int n) {
-+ long l = n;
-+ if (l < 0) {
-+ l += 0x100000000L;
-+ }
-+ l = l & 0xFFFFFFFF;
-+ l = (l >> 24) | ((l & 0x00ff0000) >> 8) | ((l & 0x0000ff00) << 8) | (l << 24);
-+ return (int) l;
-+ }
-+
-+ int windozeToUnix(int L, int H) {
-+ long L2 = zogswap(L);
-+ long H2 = zogswap(H);
-+ long unix = (H2 << 32) + L2;
-+ unix -= 11644473600L * 10000000L;
-+ unix /= 10000000L;
-+ //System.out.println("unix time: " + unix + " H2: " + H2 + " L2: " + L2);
-+ return (int) unix;
-+ }
-+
-+ String timeStr(int t, int h) {
-+ if (h == 0) {
-+ // x11vnc/libvncserver unix
-+ t = zogswap(t);
-+ } else {
-+ // ultra (except if h==0 by chance)
-+ t = windozeToUnix(t, h);
-+ }
-+ long tl = (long) t;
-+ Date date = new Date(tl * 1000);
-+ if (true) {
-+ return date.toString();
-+ } else {
-+ return DateFormat.getDateTimeInstance().format(date);
-+ }
-+ }
-+
-+ String dotPast(double f, int n) {
-+ String fs = "" + f;
-+ int i = fs.lastIndexOf(".") + n;
-+ if (i >= 0) {
-+ int len = fs.length();
-+ if (i >= len) {
-+ i = len-1;
-+ }
-+ fs = fs.substring(0, i);
-+ }
-+ return fs;
-+ }
-+ String sizeStr(int s) {
-+ s = zogswap(s);
-+ if (s < 0) {
-+ return s + "? B";
-+ } else if (s < 1024) {
-+ return s + " B";
-+ } else if (s < 1024 * 1024) {
-+ double k = s / 1024.0;
-+ String ks = dotPast(k, 3);
-+
-+ return s + " (" + ks + " KB)";
-+ } else {
-+ double m = s / (1024.0*1024.0);
-+ String ms = dotPast(m, 3);
-+ return s + " (" + ms + " MB)";
-+ }
-+ }
-+
- //Internally used to receive directory content from server
- //Here, the server sends one file/directory with it's attributes
- void readFTPMsgDirectoryListContent() throws IOException
-@@ -1217,17 +1452,32 @@
- dwReserved0,
- dwReserved1;
- long ftCreationTime, ftLastAccessTime, ftLastWriteTime;
-+ int ftCreationTimeL, ftLastAccessTimeL, ftLastWriteTimeL;
-+ int ftCreationTimeH, ftLastAccessTimeH, ftLastWriteTimeH;
- char cFileName, cAlternateFileName;
- int length = 0;
- is.readInt();
- length = is.readInt();
-+
-+ char[] chars = new char[4*length];
-+ int char_cnt = 0;
-+ for (int i = 0; i < chars.length; i++) {
-+ chars[i] = '\0';
-+ }
-+
- dwFileAttributes = is.readInt();
- length -= 4;
-- ftCreationTime = is.readLong();
-+ //ftCreationTime = is.readLong();
-+ ftCreationTimeL = is.readInt();
-+ ftCreationTimeH = is.readInt();
- length -= 8;
-- ftLastAccessTime = is.readLong();
-+ //ftLastAccessTime = is.readLong();
-+ ftLastAccessTimeL = is.readInt();
-+ ftLastAccessTimeH = is.readInt();
- length -= 8;
-- ftLastWriteTime = is.readLong();
-+ //ftLastWriteTime = is.readLong();
-+ ftLastWriteTimeL = is.readInt();
-+ ftLastWriteTimeH = is.readInt();
- length -= 8;
- nFileSizeHigh = is.readInt();
- length -= 4;
-@@ -1239,10 +1489,12 @@
- length -= 4;
- cFileName = (char) is.readUnsignedByte();
- length--;
-+ chars[char_cnt++] = cFileName;
- while (cFileName != '\0')
- {
- fileName += cFileName;
- cFileName = (char) is.readUnsignedByte();
-+ chars[char_cnt++] = cFileName;
- length--;
- }
- cAlternateFileName = (char) is.readByte();
-@@ -1253,7 +1505,28 @@
- cAlternateFileName = (char) is.readUnsignedByte();
- length--;
- }
-- if (dwFileAttributes == 268435456
-+ String guessed = guess_encoding(chars);
-+ if (!guessed.equals("ASCII")) {
-+ System.out.println("guess: " + guessed + "\t" + fileName);
-+ }
-+ if (guessed.equals("UTF-8")) {
-+ try {
-+ byte[] bytes = new byte[char_cnt-1];
-+ for (int i=0; i < char_cnt-1; i++) {
-+ bytes[i] = (byte) chars[i];
-+ }
-+ String newstr = new String(bytes, "UTF-8");
-+ fileName = newstr;
-+ } catch (Exception e) {
-+ System.out.println("failed to convert bytes to UTF-8 based string");
-+ }
-+ }
-+ for (int i = 0; i < char_cnt; i++) {
-+ //System.out.println("char[" + i + "]\t" + (int) chars[i]);
-+ }
-+ if (fileName.length() <= 0) {
-+ ;
-+ } else if (dwFileAttributes == 268435456
- || dwFileAttributes == 369098752
- || dwFileAttributes == 285212672
- || dwFileAttributes == 271056896
-@@ -1263,11 +1536,74 @@
- || dwFileAttributes == 369623040)
- {
- fileName = " [" + fileName + "]";
-- remoteDirsList.add(fileName); // sf@2004
-- }
-- else
-- {
-- remoteFilesList.add(" " + fileName); // sf@2004
-+// begin runge/x11vnc
-+// remoteDirsList.add(fileName); // sf@2004
-+ int i = -1;
-+ String t1 = fileName.toLowerCase();
-+ for (int j = 0; j < remoteDirsList.size(); j++) {
-+ String t = (String) remoteDirsList.get(j);
-+ String t2 = t.toLowerCase();
-+ if (t1.compareTo(t2) < 0) {
-+ i = j;
-+ break;
-+ }
-+ }
-+ //String s = "Lastmod: " + timeStr(ftLastWriteTimeL, ftLastWriteTimeH) + " " + fileName;
-+ String f2 = fileName;
-+ if (f2.length() < 24) {
-+ for (int ik = f2.length(); ik < 24; ik++) {
-+ f2 = f2 + " ";
-+ }
-+ }
-+ String s = f2 + " \tLastmod: " + timeStr(ftLastWriteTimeL, ftLastWriteTimeH) + " \t\tSize: " + sizeStr(nFileSizeLow);
-+ //s = fileName + " Lastmod: " + zogswap(ftLastWriteTimeL);
-+ if (i >= 0) {
-+ remoteDirsList.add(i, fileName);
-+ remoteDirsListInfo.add(i, s);
-+ } else {
-+ remoteDirsList.add(fileName);
-+ remoteDirsListInfo.add(s);
-+ }
-+// end runge/x11vnc
-+ } else {
-+// begin runge/x11vnc
-+// remoteFilesList.add(" " + fileName); // sf@2004
-+
-+ fileName = " " + fileName;
-+ int i = -1;
-+ String t1 = fileName.toLowerCase();
-+ for (int j = 0; j < remoteFilesList.size(); j++) {
-+ String t = (String) remoteFilesList.get(j);
-+ String t2 = t.toLowerCase();
-+ if (t1.compareTo(t2) < 0) {
-+ i = j;
-+ break;
-+ }
-+ }
-+ String f2 = fileName;
-+ if (f2.length() < 24) {
-+ for (int ik = f2.length(); ik < 24; ik++) {
-+ f2 = f2 + " ";
-+ }
-+ }
-+
-+if (false) {
-+System.out.println("fileName: " + f2);
-+System.out.println("ftLastWriteTimeL: " + ftLastWriteTimeL);
-+System.out.println("ftLastWriteTimeH: " + ftLastWriteTimeH);
-+System.out.println("nFileSizeLow: " + nFileSizeLow);
-+}
-+
-+ String s = f2 + " \tLastmod: " + timeStr(ftLastWriteTimeL, ftLastWriteTimeH) + " \t\tSize: " + sizeStr(nFileSizeLow);
-+ //s = fileName + " Lastmod: " + ftLastWriteTimeL + "/" + zogswap(ftLastWriteTimeL) + " Size: " + nFileSizeLow + "/" + zogswap(nFileSizeLow);
-+ if (i >= 0) {
-+ remoteFilesList.add(i, fileName);
-+ remoteFilesListInfo.add(i, s);
-+ } else {
-+ remoteFilesList.add(fileName);
-+ remoteFilesListInfo.add(s);
-+ }
-+// end runge/x11vnc
- }
-
- // a.add(fileName);
-@@ -1282,14 +1618,32 @@
-
- // sf@2004
- a.clear();
-- for (int i = 0; i < remoteDirsList.size(); i++)
-+ b.clear();
-+ for (int i = 0; i < remoteDirsList.size(); i++) {
- a.add(remoteDirsList.get(i));
-- for (int i = 0; i < remoteFilesList.size(); i++)
-+ b.add(remoteDirsListInfo.get(i));
-+ }
-+ for (int i = 0; i < remoteFilesList.size(); i++) {
- a.add(remoteFilesList.get(i));
-+
-+ b.add(remoteFilesListInfo.get(i));
-+ }
- remoteDirsList.clear();
-+ remoteDirsListInfo.clear();
- remoteFilesList.clear();
-+ remoteFilesListInfo.clear();
-
-- viewer.ftp.printDirectory(a);
-+// begin runge/x11vnc
-+ // Hack for double listing at startup... probably libvncserver bug..
-+ readServerDriveListCnt++;
-+ if (readServerDriveListCnt == 2) {
-+ if (System.currentTimeMillis() - readServerDriveListTime < 2000) {
-+//System.out.println("readServerDriveListCnt skip " + readServerDriveListCnt);
-+ return;
-+ }
-+ }
-+// end runge/x11vnc
-+ viewer.ftp.printDirectory(a, b);
- }
-
- //Internally used to signify the drive requested is not ready
-@@ -1299,6 +1653,8 @@
- System.out.println("Remote Drive unavailable");
- viewer.ftp.connectionStatus.setText(" > WARNING - Remote Drive unavailable (possibly restricted access or media not present)");
- viewer.ftp.remoteStatus.setText("WARNING: Remote Drive unavailable");
-+ viewer.ftp.historyComboBox.insertItemAt(new String(" > WARNING: Remote Drive unavailable."), 0);
-+ viewer.ftp.historyComboBox.setSelectedIndex(0);
- }
-
- //Call this method to request the list of drives on the server.
-@@ -1306,12 +1662,11 @@
- {
- try
- {
-- viewer.rfb.writeRfbFileTransferMsg(
-- RfbProto.rfbDirContentRequest,
-- RfbProto.rfbRDrivesList,
-- 0,
-- 0,
-- null);
-+ viewer.rfb.writeRfbFileTransferMsg(RfbProto.rfbDirContentRequest, RfbProto.rfbRDrivesList, 0, 0, null);
-+// begin runge/x11vnc
-+ readServerDriveListCnt = 0;
-+ readServerDriveListTime = System.currentTimeMillis();
-+// end runge/x11vnc
- }
- catch (IOException e)
- {
-@@ -1355,21 +1710,21 @@
- int h,
- boolean incremental)
- throws IOException {
-- if (!viewer.ftp.isVisible()) {
-- byte[] b = new byte[10];
-+ if (!viewer.ftp.isVisible()) {
-+ byte[] b = new byte[10];
-
-- b[0] = (byte) FramebufferUpdateRequest;
-- b[1] = (byte) (incremental ? 1 : 0);
-- b[2] = (byte) ((x >> 8) & 0xff);
-- b[3] = (byte) (x & 0xff);
-- b[4] = (byte) ((y >> 8) & 0xff);
-- b[5] = (byte) (y & 0xff);
-- b[6] = (byte) ((w >> 8) & 0xff);
-- b[7] = (byte) (w & 0xff);
-- b[8] = (byte) ((h >> 8) & 0xff);
-- b[9] = (byte) (h & 0xff);
-+ b[0] = (byte) FramebufferUpdateRequest;
-+ b[1] = (byte) (incremental ? 1 : 0);
-+ b[2] = (byte) ((x >> 8) & 0xff);
-+ b[3] = (byte) (x & 0xff);
-+ b[4] = (byte) ((y >> 8) & 0xff);
-+ b[5] = (byte) (y & 0xff);
-+ b[6] = (byte) ((w >> 8) & 0xff);
-+ b[7] = (byte) (w & 0xff);
-+ b[8] = (byte) ((h >> 8) & 0xff);
-+ b[9] = (byte) (h & 0xff);
-
-- os.write(b);
-+ os.write(b);
- }
- }
-
-@@ -1482,7 +1837,13 @@
- b[6] = (byte) ((text.length() >> 8) & 0xff);
- b[7] = (byte) (text.length() & 0xff);
-
-- System.arraycopy(text.getBytes(), 0, b, 8, text.length());
-+ if (false && max_char(text) > 255) {
-+ System.arraycopy(text.getBytes("UTF-8"), 0, b, 8, text.length());
-+ } else if (max_char(text) > 127) {
-+ System.arraycopy(text.getBytes("ISO-8859-1"), 0, b, 8, text.length());
-+ } else {
-+ System.arraycopy(text.getBytes(), 0, b, 8, text.length());
-+ }
-
- os.write(b);
- // }
-@@ -1506,6 +1867,37 @@
- final static int META_MASK = InputEvent.META_MASK;
- final static int ALT_MASK = InputEvent.ALT_MASK;
-
-+ void writeWheelEvent(MouseWheelEvent evt) throws IOException {
-+ eventBufLen = 0;
-+
-+ int x = evt.getX();
-+ int y = evt.getY();
-+
-+ if (x < 0) x = 0;
-+ if (y < 0) y = 0;
-+
-+ int ptrmask;
-+
-+ int clicks = evt.getWheelRotation();
-+ System.out.println("writeWheelEvent: clicks: " + clicks);
-+ if (clicks > 0) {
-+ ptrmask = 16;
-+ } else if (clicks < 0) {
-+ ptrmask = 8;
-+ } else {
-+ return;
-+ }
-+
-+ eventBuf[eventBufLen++] = (byte) PointerEvent;
-+ eventBuf[eventBufLen++] = (byte) ptrmask;
-+ eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff);
-+ eventBuf[eventBufLen++] = (byte) (x & 0xff);
-+ eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff);
-+ eventBuf[eventBufLen++] = (byte) (y & 0xff);
-+
-+ os.write(eventBuf, 0, eventBufLen);
-+ }
-+
- //
- // Write a pointer event message. We may need to send modifier key events
- // around it to set the correct modifier state.
-@@ -1610,6 +2002,21 @@
-
- boolean down = (evt.getID() == KeyEvent.KEY_PRESSED);
-
-+ if (viewer.debugKeyboard) {
-+ System.out.println("----------------------------------------");
-+ System.out.println("evt.getKeyChar: " + evt.getKeyChar());
-+ System.out.println("getKeyText: " + KeyEvent.getKeyText(evt.getKeyCode()));
-+ System.out.println("evt.getKeyCode: " + evt.getKeyCode());
-+ System.out.println("evt.getID: " + evt.getID());
-+ System.out.println("evt.getKeyLocation: " + evt.getKeyLocation());
-+ System.out.println("evt.isActionKey: " + evt.isActionKey());
-+ System.out.println("evt.isControlDown: " + evt.isControlDown());
-+ System.out.println("evt.getModifiers: " + evt.getModifiers());
-+ System.out.println("getKeyModifiersText: " + KeyEvent.getKeyModifiersText(evt.getModifiers()));
-+ System.out.println("evt.paramString: " + evt.paramString());
-+ }
-+
-+
- int key;
- if (evt.isActionKey()) {
-
-@@ -1685,6 +2092,9 @@
- default :
- return;
- }
-+ if (key == 0xffc2 && viewer.mapF5_to_atsign) {
-+ key = 0x40;
-+ }
-
- } else {
-
-@@ -1794,6 +2204,16 @@
- int oldModifiers = 0;
-
- void writeModifierKeyEvents(int newModifiers) {
-+ if(viewer.forbid_Ctrl_Alt) {
-+ if ((newModifiers & CTRL_MASK) != 0 && (newModifiers & ALT_MASK) != 0) {
-+ int orig = newModifiers;
-+ newModifiers &= ~ALT_MASK;
-+ newModifiers &= ~CTRL_MASK;
-+ if (viewer.debugKeyboard) {
-+ System.out.println("Ctrl+Alt modifiers: " + orig + " -> " + newModifiers);
-+ }
-+ }
-+ }
- if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK))
- writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0);
-
-diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
---- JavaViewer.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500
-+++ JavaViewer/SSLSocketToMe.java 2010-07-10 19:18:06.000000000 -0400
-@@ -0,0 +1,2067 @@
-+/*
-+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
-+ *
-+ * Copyright (c) 2006 Karl J. Runge <runge@karlrunge.com>
-+ * All rights reserved.
-+ *
-+ * This is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This software is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this software; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ *
-+ */
-+
-+import java.net.*;
-+import java.io.*;
-+import javax.net.ssl.*;
-+import java.util.*;
-+
-+import java.security.*;
-+import java.security.cert.*;
-+import java.security.spec.*;
-+import java.security.cert.Certificate;
-+import java.security.cert.CertificateFactory;
-+
-+import java.awt.*;
-+import java.awt.event.*;
-+
-+public class SSLSocketToMe {
-+
-+ /* basic member data: */
-+ String host;
-+ int port;
-+ VncViewer viewer;
-+
-+ boolean debug = true;
-+ boolean debug_certs = false;
-+
-+ /* sockets */
-+ SSLSocket socket = null;
-+ SSLSocketFactory factory;
-+
-+ /* fallback for Proxy connection */
-+ boolean proxy_in_use = false;
-+ boolean proxy_failure = false;
-+ public DataInputStream is = null;
-+ public OutputStream os = null;
-+
-+ /* strings from user WRT proxy: */
-+ String proxy_auth_string = null;
-+ String proxy_dialog_host = null;
-+ int proxy_dialog_port = 0;
-+
-+ Socket proxySock;
-+ DataInputStream proxy_is;
-+ OutputStream proxy_os;
-+
-+ /* trust contexts */
-+ SSLContext trustloc_ctx;
-+ SSLContext trustall_ctx;
-+ SSLContext trustsrv_ctx;
-+ SSLContext trusturl_ctx;
-+ SSLContext trustone_ctx;
-+
-+ /* corresponding trust managers */
-+ TrustManager[] trustAllCerts;
-+ TrustManager[] trustSrvCert;
-+ TrustManager[] trustUrlCert;
-+ TrustManager[] trustOneCert;
-+
-+ /* client-side SSL auth key (oneTimeKey=...) */
-+ KeyManager[] mykey = null;
-+
-+ boolean user_wants_to_see_cert = true;
-+ String cert_fail = null;
-+
-+ /* cert(s) we retrieve from Web server, VNC server, or serverCert param: */
-+ java.security.cert.Certificate[] trustallCerts = null;
-+ java.security.cert.Certificate[] trustsrvCerts = null;
-+ java.security.cert.Certificate[] trusturlCerts = null;
-+
-+ /* utility to decode hex oneTimeKey=... and serverCert=... */
-+ byte[] hex2bytes(String s) {
-+ byte[] bytes = new byte[s.length()/2];
-+ for (int i=0; i<s.length()/2; i++) {
-+ int j = 2*i;
-+ try {
-+ int val = Integer.parseInt(s.substring(j, j+2), 16);
-+ if (val > 127) {
-+ val -= 256;
-+ }
-+ Integer I = new Integer(val);
-+ bytes[i] = Byte.decode(I.toString()).byteValue();
-+
-+ } catch (Exception e) {
-+ ;
-+ }
-+ }
-+ return bytes;
-+ }
-+
-+ SSLSocketToMe(String h, int p, VncViewer v) throws Exception {
-+ host = h;
-+ port = p;
-+ viewer = v;
-+
-+ debug_certs = v.debugCerts;
-+
-+ /* we will first try default factory for certification: */
-+
-+ factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
-+
-+ dbg("SSL startup: " + host + " " + port);
-+
-+
-+ /* create trust managers to be used if initial handshake fails: */
-+
-+ trustAllCerts = new TrustManager[] {
-+ /*
-+ * this one accepts everything. Only used if user
-+ * has disabled checking (trustAllVncCerts=yes)
-+ * or when we grab the cert to show it to them in
-+ * a dialog and ask them to manually verify/accept it.
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) {
-+ /* empty */
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) {
-+ /* empty */
-+ dbg("ALL: an untrusted connect to grab cert.");
-+ }
-+ }
-+ };
-+
-+ trustUrlCert = new TrustManager[] {
-+ /*
-+ * this one accepts only the retrieved server
-+ * cert by SSLSocket by this applet and stored in
-+ * trusturlCerts.
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ throw new CertificateException("No Clients (URL)");
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ /* we want to check 'certs' against 'trusturlCerts' */
-+ if (trusturlCerts == null) {
-+ throw new CertificateException(
-+ "No Trust url Certs array.");
-+ }
-+ if (trusturlCerts.length < 1) {
-+ throw new CertificateException(
-+ "No Trust url Certs.");
-+ }
-+ if (certs == null) {
-+ throw new CertificateException(
-+ "No this-certs array.");
-+ }
-+ if (certs.length < 1) {
-+ throw new CertificateException(
-+ "No this-certs Certs.");
-+ }
-+ if (certs.length != trusturlCerts.length) {
-+ throw new CertificateException(
-+ "certs.length != trusturlCerts.length " + certs.length + " " + trusturlCerts.length);
-+ }
-+ boolean ok = true;
-+ for (int i = 0; i < certs.length; i++) {
-+ if (! trusturlCerts[i].equals(certs[i])) {
-+ ok = false;
-+ dbg("URL: cert mismatch at i=" + i);
-+ dbg("URL: cert mismatch cert" + certs[i]);
-+ dbg("URL: cert mismatch url" + trusturlCerts[i]);
-+ if (cert_fail == null) {
-+ cert_fail = "cert-mismatch";
-+ }
-+ }
-+ if (debug_certs) {
-+ dbg("\n***********************************************");
-+ dbg("URL: cert info at i=" + i);
-+ dbg("URL: cert info cert" + certs[i]);
-+ dbg("===============================================");
-+ dbg("URL: cert info url" + trusturlCerts[i]);
-+ dbg("***********************************************");
-+ }
-+ }
-+ if (!ok) {
-+ throw new CertificateException(
-+ "Server Cert Chain != URL Cert Chain.");
-+ }
-+ dbg("URL: trusturlCerts[i] matches certs[i] i=0:" + (certs.length-1));
-+ }
-+ }
-+ };
-+
-+ trustSrvCert = new TrustManager[] {
-+ /*
-+ * this one accepts cert given to us in the serverCert
-+ * Applet Parameter we were started with. It is
-+ * currently a fatal error if the VNC Server's cert
-+ * doesn't match it.
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ throw new CertificateException("No Clients (SRV)");
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ /* we want to check 'certs' against 'trustsrvCerts' */
-+ if (trustsrvCerts == null) {
-+ throw new CertificateException(
-+ "No Trust srv Certs array.");
-+ }
-+ if (trustsrvCerts.length < 1) {
-+ throw new CertificateException(
-+ "No Trust srv Certs.");
-+ }
-+ if (certs == null) {
-+ throw new CertificateException(
-+ "No this-certs array.");
-+ }
-+ if (certs.length < 1) {
-+ throw new CertificateException(
-+ "No this-certs Certs.");
-+ }
-+ if (certs.length != trustsrvCerts.length) {
-+ throw new CertificateException(
-+ "certs.length != trustsrvCerts.length " + certs.length + " " + trustsrvCerts.length);
-+ }
-+ boolean ok = true;
-+ for (int i = 0; i < certs.length; i++) {
-+ if (! trustsrvCerts[i].equals(certs[i])) {
-+ ok = false;
-+ dbg("SRV: cert mismatch at i=" + i);
-+ dbg("SRV: cert mismatch cert" + certs[i]);
-+ dbg("SRV: cert mismatch srv" + trustsrvCerts[i]);
-+ if (cert_fail == null) {
-+ cert_fail = "server-cert-mismatch";
-+ }
-+ }
-+ if (debug_certs) {
-+ dbg("\n***********************************************");
-+ dbg("SRV: cert info at i=" + i);
-+ dbg("SRV: cert info cert" + certs[i]);
-+ dbg("===============================================");
-+ dbg("SRV: cert info srv" + trustsrvCerts[i]);
-+ dbg("***********************************************");
-+ }
-+ }
-+ if (!ok) {
-+ throw new CertificateException(
-+ "Server Cert Chain != serverCert Applet Parameter Cert Chain.");
-+ }
-+ dbg("SRV: trustsrvCerts[i] matches certs[i] i=0:" + (certs.length-1));
-+ }
-+ }
-+ };
-+
-+ trustOneCert = new TrustManager[] {
-+ /*
-+ * this one accepts only the retrieved server
-+ * cert by SSLSocket by this applet we stored in
-+ * trustallCerts that user has accepted or applet
-+ * parameter trustAllVncCerts=yes is set. This is
-+ * for when we reconnect after the user has manually
-+ * accepted the trustall cert in the dialog (or set
-+ * trustAllVncCerts=yes applet param.)
-+ */
-+ new X509TrustManager() {
-+ public java.security.cert.X509Certificate[]
-+ getAcceptedIssuers() {
-+ return null;
-+ }
-+ public void checkClientTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ throw new CertificateException("No Clients (ONE)");
-+ }
-+ public void checkServerTrusted(
-+ java.security.cert.X509Certificate[] certs,
-+ String authType) throws CertificateException {
-+ /* we want to check 'certs' against 'trustallCerts' */
-+ if (trustallCerts == null) {
-+ throw new CertificateException(
-+ "No Trust All Server Certs array.");
-+ }
-+ if (trustallCerts.length < 1) {
-+ throw new CertificateException(
-+ "No Trust All Server Certs.");
-+ }
-+ if (certs == null) {
-+ throw new CertificateException(
-+ "No this-certs array.");
-+ }
-+ if (certs.length < 1) {
-+ throw new CertificateException(
-+ "No this-certs Certs.");
-+ }
-+ if (certs.length != trustallCerts.length) {
-+ throw new CertificateException(
-+ "certs.length != trustallCerts.length " + certs.length + " " + trustallCerts.length);
-+ }
-+ boolean ok = true;
-+ for (int i = 0; i < certs.length; i++) {
-+ if (! trustallCerts[i].equals(certs[i])) {
-+ ok = false;
-+ dbg("ONE: cert mismatch at i=" + i);
-+ dbg("ONE: cert mismatch cert" + certs[i]);
-+ dbg("ONE: cert mismatch all" + trustallCerts[i]);
-+ }
-+ if (debug_certs) {
-+ dbg("\n***********************************************");
-+ dbg("ONE: cert info at i=" + i);
-+ dbg("ONE: cert info cert" + certs[i]);
-+ dbg("===============================================");
-+ dbg("ONE: cert info all" + trustallCerts[i]);
-+ dbg("***********************************************");
-+ }
-+ }
-+ if (!ok) {
-+ throw new CertificateException(
-+ "Server Cert Chain != TRUSTALL Cert Chain.");
-+ }
-+ dbg("ONE: trustallCerts[i] matches certs[i] i=0:" + (certs.length-1));
-+ }
-+ }
-+ };
-+
-+ /*
-+ * The above TrustManagers are used:
-+ *
-+ * 1) to retrieve the server cert in case of failure to
-+ * display it to the user in a dialog.
-+ * 2) to subsequently connect to the server if user agrees.
-+ */
-+
-+ /*
-+ * build oneTimeKey cert+key if supplied in applet parameter:
-+ */
-+ if (viewer.oneTimeKey != null && viewer.oneTimeKey.equals("PROMPT")) {
-+ ClientCertDialog d = new ClientCertDialog();
-+ viewer.oneTimeKey = d.queryUser();
-+ }
-+ if (viewer.oneTimeKey != null && viewer.oneTimeKey.indexOf(",") > 0) {
-+ int idx = viewer.oneTimeKey.indexOf(",");
-+
-+ String onetimekey = viewer.oneTimeKey.substring(0, idx);
-+ byte[] key = hex2bytes(onetimekey);
-+ String onetimecert = viewer.oneTimeKey.substring(idx+1);
-+ byte[] cert = hex2bytes(onetimecert);
-+
-+ KeyFactory kf = KeyFactory.getInstance("RSA");
-+ PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
-+ PrivateKey ff = kf.generatePrivate (keysp);
-+ if (debug_certs) {
-+ dbg("one time key " + ff);
-+ }
-+
-+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
-+ Collection c = cf.generateCertificates(new ByteArrayInputStream(cert));
-+ Certificate[] certs = new Certificate[c.toArray().length];
-+ if (c.size() == 1) {
-+ Certificate tmpcert = cf.generateCertificate(new ByteArrayInputStream(cert));
-+ if (debug_certs) {
-+ dbg("one time cert" + tmpcert);
-+ }
-+ certs[0] = tmpcert;
-+ } else {
-+ certs = (Certificate[]) c.toArray();
-+ }
-+
-+ KeyStore ks = KeyStore.getInstance("JKS");
-+ ks.load(null, null);
-+ ks.setKeyEntry("onetimekey", ff, "".toCharArray(), certs);
-+ String da = KeyManagerFactory.getDefaultAlgorithm();
-+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(da);
-+ kmf.init(ks, "".toCharArray());
-+
-+ mykey = kmf.getKeyManagers();
-+ }
-+
-+ /*
-+ * build serverCert cert if supplied in applet parameter:
-+ */
-+ if (viewer.serverCert != null) {
-+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
-+ byte[] cert = hex2bytes(viewer.serverCert);
-+ Collection c = cf.generateCertificates(new ByteArrayInputStream(cert));
-+ trustsrvCerts = new Certificate[c.toArray().length];
-+ if (c.size() == 1) {
-+ Certificate tmpcert = cf.generateCertificate(new ByteArrayInputStream(cert));
-+ trustsrvCerts[0] = tmpcert;
-+ } else {
-+ trustsrvCerts = (Certificate[]) c.toArray();
-+ }
-+ }
-+
-+ /* the trust loc certs context: */
-+ try {
-+ trustloc_ctx = SSLContext.getInstance("SSL");
-+
-+ /*
-+ * below is a failed attempt to get jvm's default
-+ * trust manager using null (below) makes it so
-+ * for HttpsURLConnection the server cannot be
-+ * verified (no prompting.)
-+ */
-+ if (false) {
-+ boolean didit = false;
-+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-+ tmf.init((KeyStore) null);
-+ TrustManager [] tml = tmf.getTrustManagers();
-+ for (int i = 0; i < tml.length; i++) {
-+ TrustManager tm = tml[i];
-+ if (tm instanceof X509TrustManager) {
-+ TrustManager tm1[] = new TrustManager[1];
-+ tm1[0] = tm;
-+ trustloc_ctx.init(mykey, tm1, null);
-+ didit = true;
-+ break;
-+ }
-+ }
-+ if (!didit) {
-+ trustloc_ctx.init(mykey, null, null);
-+ }
-+ } else {
-+ /* we have to set trust manager to null */
-+ trustloc_ctx.init(mykey, null, null);
-+ }
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustloc_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust all certs context: */
-+ try {
-+ trustall_ctx = SSLContext.getInstance("SSL");
-+ trustall_ctx.init(mykey, trustAllCerts, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustall_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust url certs context: */
-+ try {
-+ trusturl_ctx = SSLContext.getInstance("SSL");
-+ trusturl_ctx.init(mykey, trustUrlCert, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trusturl_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust srv certs context: */
-+ try {
-+ trustsrv_ctx = SSLContext.getInstance("SSL");
-+ trustsrv_ctx.init(mykey, trustSrvCert, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustsrv_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+
-+ /* the trust the one cert from server context: */
-+ try {
-+ trustone_ctx = SSLContext.getInstance("SSL");
-+ trustone_ctx.init(mykey, trustOneCert, new
-+ java.security.SecureRandom());
-+
-+ } catch (Exception e) {
-+ String msg = "SSL trustone_ctx FAILED.";
-+ dbg(msg);
-+ throw new Exception(msg);
-+ }
-+ }
-+
-+ /*
-+ * we call this early on to 1) check for a proxy, 2) grab
-+ * Browser/JVM accepted HTTPS cert.
-+ */
-+ public void check_for_proxy_and_grab_vnc_server_cert() {
-+
-+ trusturlCerts = null;
-+ proxy_in_use = false;
-+
-+ if (viewer.ignoreProxy) {
-+ /* applet param says skip it. */
-+ /* the downside is we do not set trusturlCerts for comparison later... */
-+ /* nor do we autodetect x11vnc for GET=1. */
-+ return;
-+ }
-+
-+ dbg("------------------------------------------------");
-+ dbg("Into check_for_proxy_and_grab_vnc_server_cert():");
-+
-+ dbg("TRYING HTTPS:");
-+ String ustr = "https://" + host + ":";
-+ if (viewer.httpsPort != null) {
-+ ustr += viewer.httpsPort;
-+ } else {
-+ ustr += port;
-+ }
-+ ustr += viewer.urlPrefix + "/check.https.proxy.connection";
-+ dbg("ustr is: " + ustr);
-+
-+ try {
-+ /* prepare for an HTTPS URL connection to host:port */
-+ URL url = new URL(ustr);
-+ HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
-+
-+ if (mykey != null) {
-+ /* with oneTimeKey (mykey) we can't use the default SSL context */
-+ if (trustsrvCerts != null) {
-+ dbg("passing trustsrv_ctx to HttpsURLConnection to provide client cert.");
-+ https.setSSLSocketFactory(trustsrv_ctx.getSocketFactory());
-+ } else if (trustloc_ctx != null) {
-+ dbg("passing trustloc_ctx to HttpsURLConnection to provide client cert.");
-+ https.setSSLSocketFactory(trustloc_ctx.getSocketFactory());
-+ }
-+ }
-+
-+ https.setUseCaches(false);
-+ https.setRequestMethod("GET");
-+ https.setRequestProperty("Pragma", "No-Cache");
-+ https.setRequestProperty("Proxy-Connection", "Keep-Alive");
-+ https.setDoInput(true);
-+
-+ dbg("trying https.connect()");
-+ https.connect();
-+
-+ dbg("trying https.getServerCertificates()");
-+ trusturlCerts = https.getServerCertificates();
-+
-+ if (trusturlCerts == null) {
-+ dbg("set trusturlCerts to null!");
-+ } else {
-+ dbg("set trusturlCerts to non-null");
-+ }
-+
-+ if (https.usingProxy()) {
-+ proxy_in_use = true;
-+ dbg("An HTTPS proxy is in use. There may be connection problems.");
-+ }
-+
-+ dbg("trying https.getContent()");
-+ Object output = https.getContent();
-+ dbg("trying https.disconnect()");
-+ https.disconnect();
-+ if (! viewer.GET) {
-+ String header = https.getHeaderField("VNC-Server");
-+ if (header != null && header.startsWith("x11vnc")) {
-+ dbg("detected x11vnc server (1), setting GET=1");
-+ viewer.GET = true;
-+ }
-+ }
-+
-+ } catch(Exception e) {
-+ dbg("HttpsURLConnection: " + e.getMessage());
-+ }
-+
-+ if (proxy_in_use) {
-+ dbg("exit check_for_proxy_and_grab_vnc_server_cert():");
-+ dbg("------------------------------------------------");
-+ return;
-+ } else if (trusturlCerts != null && !viewer.forceProxy) {
-+ /* Allow user to require HTTP check? use forceProxy for now. */
-+ dbg("SKIPPING HTTP PROXY CHECK: got trusturlCerts, assuming proxy info is correct.");
-+ dbg("exit check_for_proxy_and_grab_vnc_server_cert():");
-+ dbg("------------------------------------------------");
-+ return;
-+ }
-+
-+ /*
-+ * XXX need to remember scenario where this extra check
-+ * gives useful info. User's Browser proxy settings?
-+ */
-+ dbg("TRYING HTTP:");
-+ ustr = "http://" + host + ":" + port;
-+ ustr += viewer.urlPrefix + "/index.vnc";
-+ dbg("ustr is: " + ustr);
-+
-+ try {
-+ /* prepare for an HTTP URL connection to the same host:port (but not httpsPort) */
-+ URL url = new URL(ustr);
-+ HttpURLConnection http = (HttpURLConnection)
-+ url.openConnection();
-+
-+ http.setUseCaches(false);
-+ http.setRequestMethod("GET");
-+ http.setRequestProperty("Pragma", "No-Cache");
-+ http.setRequestProperty("Proxy-Connection", "Keep-Alive");
-+ http.setDoInput(true);
-+
-+ dbg("trying http.connect()");
-+ http.connect();
-+
-+ if (http.usingProxy()) {
-+ proxy_in_use = true;
-+ dbg("An HTTP proxy is in use. There may be connection problems.");
-+ }
-+ dbg("trying http.getContent()");
-+ Object output = http.getContent();
-+ dbg("trying http.disconnect()");
-+ http.disconnect();
-+ if (! viewer.GET) {
-+ String header = http.getHeaderField("VNC-Server");
-+ if (header != null && header.startsWith("x11vnc")) {
-+ dbg("detected x11vnc server (2), setting GET=1");
-+ viewer.GET = true;
-+ }
-+ }
-+ } catch(Exception e) {
-+ dbg("HttpURLConnection: " + e.getMessage());
-+ }
-+ dbg("exit check_for_proxy_and_grab_vnc_server_cert():");
-+ dbg("------------------------------------------------");
-+ }
-+
-+ public Socket connectSock() throws IOException {
-+ /*
-+ * first try a https connection to detect a proxy, and
-+ * grab the VNC server cert at the same time:
-+ */
-+ check_for_proxy_and_grab_vnc_server_cert();
-+
-+ boolean srv_cert = false;
-+
-+ if (trustsrvCerts != null) {
-+ /* applet parameter suppled serverCert */
-+ dbg("viewer.trustSrvCert-0 using trustsrv_ctx");
-+ factory = trustsrv_ctx.getSocketFactory();
-+ srv_cert = true;
-+ } else if (viewer.trustAllVncCerts) {
-+ /* trust all certs (no checking) */
-+ dbg("viewer.trustAllVncCerts-0 using trustall_ctx");
-+ factory = trustall_ctx.getSocketFactory();
-+ } else if (trusturlCerts != null) {
-+ /* trust certs the Browser/JVM accepted in check_for_proxy... */
-+ dbg("using trusturl_ctx");
-+ factory = trusturl_ctx.getSocketFactory();
-+ } else {
-+ /* trust the local defaults */
-+ dbg("using trustloc_ctx");
-+ factory = trustloc_ctx.getSocketFactory();
-+ }
-+
-+ socket = null;
-+
-+ try {
-+ if (proxy_in_use && viewer.forceProxy) {
-+ throw new Exception("forcing proxy (forceProxy)");
-+ } else if (viewer.CONNECT != null) {
-+ throw new Exception("forcing CONNECT");
-+ }
-+
-+ int timeout = 6;
-+ if (timeout > 0) {
-+ socket = (SSLSocket) factory.createSocket();
-+ InetSocketAddress inetaddr = new InetSocketAddress(host, port);
-+ dbg("Using timeout of " + timeout + " secs to: " + host + ":" + port);
-+ socket.connect(inetaddr, timeout * 1000);
-+ } else {
-+ socket = (SSLSocket) factory.createSocket(host, port);
-+ }
-+
-+ } catch (Exception esock) {
-+ dbg("socket error: " + esock.getMessage());
-+ if (proxy_in_use || viewer.CONNECT != null) {
-+ proxy_failure = true;
-+ if (proxy_in_use) {
-+ dbg("HTTPS proxy in use. Trying to go with it.");
-+ } else {
-+ dbg("viewer.CONNECT reverse proxy in use. Trying to go with it.");
-+ }
-+ try {
-+ socket = proxy_socket(factory);
-+ } catch (Exception e) {
-+ dbg("proxy_socket error: " + e.getMessage());
-+ }
-+ } else {
-+ /* n.b. socket is left in error state to cause ex. below. */
-+ }
-+ }
-+
-+ try {
-+ socket.startHandshake();
-+
-+ dbg("The Server Connection Verified OK on 1st try.");
-+
-+ java.security.cert.Certificate[] currentTrustedCerts;
-+ BrowserCertsDialog bcd;
-+
-+ SSLSession sess = socket.getSession();
-+ currentTrustedCerts = sess.getPeerCertificates();
-+
-+ if (viewer.trustAllVncCerts) {
-+ dbg("viewer.trustAllVncCerts-1 keeping socket.");
-+ } else if (currentTrustedCerts == null || currentTrustedCerts.length < 1) {
-+ try {
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy.");
-+ }
-+ socket = null;
-+ throw new SSLHandshakeException("no current certs");
-+ }
-+
-+ String serv = "";
-+ try {
-+ CertInfo ci = new CertInfo(currentTrustedCerts[0]);
-+ serv = ci.get_certinfo("CN");
-+ } catch (Exception e) {
-+ ;
-+ }
-+
-+ if (viewer.trustAllVncCerts) {
-+ dbg("viewer.trustAllVncCerts-2 skipping browser certs dialog");
-+ user_wants_to_see_cert = false;
-+ } else if (viewer.serverCert != null && trustsrvCerts != null) {
-+ dbg("viewer.serverCert-1 skipping browser certs dialog");
-+ user_wants_to_see_cert = false;
-+ } else if (viewer.trustUrlVncCert) {
-+ dbg("viewer.trustUrlVncCert-1 skipping browser certs dialog");
-+ user_wants_to_see_cert = false;
-+ } else {
-+ /* have a dialog with the user: */
-+ bcd = new BrowserCertsDialog(serv, host + ":" + port);
-+ dbg("browser certs dialog begin.");
-+ bcd.queryUser();
-+ dbg("browser certs dialog finished.");
-+
-+ if (bcd.showCertDialog) {
-+ String msg = "user wants to see cert";
-+ dbg(msg);
-+ user_wants_to_see_cert = true;
-+ if (cert_fail == null) {
-+ cert_fail = "user-view";
-+ }
-+ throw new SSLHandshakeException(msg);
-+ } else {
-+ user_wants_to_see_cert = false;
-+ dbg("browser certs dialog: user said yes, accept it");
-+ }
-+ }
-+
-+ } catch (SSLHandshakeException eh) {
-+ dbg("SSLHandshakeException: could not automatically verify Server.");
-+ dbg("msg: " + eh.getMessage());
-+
-+
-+ /* send a cleanup string just in case: */
-+ String getoutstr = "GET /index.vnc HTTP/1.0\r\nConnection: close\r\n\r\n";
-+
-+ try {
-+ OutputStream os = socket.getOutputStream();
-+ os.write(getoutstr.getBytes());
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy!");
-+ }
-+
-+ /* reload */
-+
-+ socket = null;
-+
-+ String reason = null;
-+
-+ if (srv_cert) {
-+ /* for serverCert usage we make this a fatal error. */
-+ throw new IOException("Fatal: VNC Server's Cert does not match Applet Parameter 'serverCert=...'");
-+ /* see below in TrustDialog were we describe this case to user anyway */
-+ }
-+
-+ /*
-+ * Reconnect, trusting any cert, so we can grab
-+ * the cert to show it to the user in a dialog
-+ * for him to manually accept. This connection
-+ * is not used for anything else.
-+ */
-+ factory = trustall_ctx.getSocketFactory();
-+ if (proxy_failure) {
-+ socket = proxy_socket(factory);
-+ } else {
-+ socket = (SSLSocket) factory.createSocket(host, port);
-+ }
-+
-+ if (debug_certs) {
-+ dbg("trusturlCerts: " + trusturlCerts);
-+ dbg("trustsrvCerts: " + trustsrvCerts);
-+ }
-+ if (trusturlCerts == null && cert_fail == null) {
-+ cert_fail = "missing-certs";
-+ }
-+
-+ try {
-+ socket.startHandshake();
-+
-+ dbg("The TrustAll Server Cert-grab Connection (trivially) Verified OK.");
-+
-+ /* grab the cert: */
-+ try {
-+ SSLSession sess = socket.getSession();
-+ trustallCerts = sess.getPeerCertificates();
-+ } catch (Exception e) {
-+ throw new Exception("Could not get " +
-+ "Peer Certificate");
-+ }
-+ if (debug_certs) {
-+ dbg("trustallCerts: " + trustallCerts);
-+ }
-+
-+ if (viewer.trustAllVncCerts) {
-+ dbg("viewer.trustAllVncCerts-3. skipping dialog, trusting everything.");
-+ } else if (! browser_cert_match()) {
-+ /*
-+ * close socket now, we will reopen after
-+ * dialog if user agrees to use the cert.
-+ */
-+ try {
-+ OutputStream os = socket.getOutputStream();
-+ os.write(getoutstr.getBytes());
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy!!");
-+ }
-+ socket = null;
-+
-+ /* dialog with user to accept cert or not: */
-+
-+ TrustDialog td= new TrustDialog(host, port,
-+ trustallCerts);
-+
-+ if (cert_fail == null) {
-+ ;
-+ } else if (cert_fail.equals("user-view")) {
-+ reason = "Reason for this Dialog:\n\n"
-+ + " You Asked to View the Certificate.";
-+ } else if (cert_fail.equals("server-cert-mismatch")) {
-+ /* this is now fatal error, see above. */
-+ reason = "Reason for this Dialog:\n\n"
-+ + " The VNC Server's Certificate does not match the Certificate\n"
-+ + " specified in the supplied 'serverCert' Applet Parameter.";
-+ } else if (cert_fail.equals("cert-mismatch")) {
-+ reason = "Reason for this Dialog:\n\n"
-+ + " The VNC Server's Certificate does not match the Website's\n"
-+ + " HTTPS Certificate (that you previously accepted; either\n"
-+ + " manually or automatically via Certificate Authority.)";
-+ } else if (cert_fail.equals("missing-certs")) {
-+ reason = "Reason for this Dialog:\n\n"
-+ + " Not all Certificates could be obtained to check.";
-+ }
-+
-+ if (! td.queryUser(reason)) {
-+ String msg = "User decided against it.";
-+ dbg(msg);
-+ throw new IOException(msg);
-+ }
-+ }
-+
-+ } catch (Exception ehand2) {
-+ dbg("** Could not TrustAll Verify Server!");
-+
-+ throw new IOException(ehand2.getMessage());
-+ }
-+
-+ /* reload again: */
-+
-+ if (socket != null) {
-+ try {
-+ socket.close();
-+ } catch (Exception e) {
-+ dbg("socket is grumpy!!!");
-+ }
-+ socket = null;
-+ }
-+
-+ /*
-+ * Now connect a 3rd time, using the cert
-+ * retrieved during connection 2 (sadly, that
-+ * the user likely blindly agreed to...)
-+ */
-+
-+ factory = trustone_ctx.getSocketFactory();
-+ if (proxy_failure) {
-+ socket = proxy_socket(factory);
-+ } else {
-+ socket = (SSLSocket) factory.createSocket(host, port);
-+ }
-+
-+ try {
-+ socket.startHandshake();
-+ dbg("TrustAll/TrustOne Server Connection Verified #3.");
-+
-+ } catch (Exception ehand3) {
-+ dbg("** Could not TrustAll/TrustOne Verify Server #3.");
-+
-+ throw new IOException(ehand3.getMessage());
-+ }
-+ }
-+
-+ /* we have socket (possibly null) at this point, so proceed: */
-+
-+ /* handle x11vnc GET=1, if applicable: */
-+ if (socket != null && viewer.GET) {
-+ String str = "GET ";
-+ str += viewer.urlPrefix;
-+ str += "/request.https.vnc.connection";
-+ str += " HTTP/1.0\r\n";
-+ str += "Pragma: No-Cache\r\n";
-+ str += "\r\n";
-+
-+ System.out.println("sending: " + str);
-+ OutputStream os = socket.getOutputStream();
-+ String type = "os";
-+
-+ if (type == "os") {
-+ os.write(str.getBytes());
-+ os.flush();
-+ System.out.println("used OutputStream");
-+ } else if (type == "bs") {
-+ BufferedOutputStream bs = new BufferedOutputStream(os);
-+ bs.write(str.getBytes());
-+ bs.flush();
-+ System.out.println("used BufferedOutputStream");
-+ } else if (type == "ds") {
-+ DataOutputStream ds = new DataOutputStream(os);
-+ ds.write(str.getBytes());
-+ ds.flush();
-+ System.out.println("used DataOutputStream");
-+ }
-+ if (false) {
-+ String rep = "";
-+ DataInputStream is = new DataInputStream(
-+ new BufferedInputStream(socket.getInputStream(), 16384));
-+ while (true) {
-+ rep += readline(is);
-+ if (rep.indexOf("\r\n\r\n") >= 0) {
-+ break;
-+ }
-+ }
-+ System.out.println("rep: " + rep);
-+ }
-+ }
-+
-+ dbg("SSL returning socket to caller.");
-+ dbg("");
-+
-+ /* could be null, let caller handle that. */
-+ return (Socket) socket;
-+ }
-+
-+ boolean browser_cert_match() {
-+ String msg = "Browser URL accept previously accepted cert";
-+
-+ if (user_wants_to_see_cert) {
-+ return false;
-+ }
-+
-+ if (viewer.serverCert != null || trustsrvCerts != null) {
-+ if (cert_fail == null) {
-+ cert_fail = "server-cert-mismatch";
-+ }
-+ }
-+ if (trustallCerts != null && trusturlCerts != null) {
-+ if (trustallCerts.length == trusturlCerts.length) {
-+ boolean ok = true;
-+ /* check toath trustallCerts (socket) equals trusturlCerts (browser) */
-+ for (int i = 0; i < trusturlCerts.length; i++) {
-+ if (! trustallCerts[i].equals(trusturlCerts[i])) {
-+ dbg("BCM: cert mismatch at i=" + i);
-+ dbg("BCM: cert mismatch url" + trusturlCerts[i]);
-+ dbg("BCM: cert mismatch all" + trustallCerts[i]);
-+ ok = false;
-+ }
-+ }
-+ if (ok) {
-+ System.out.println(msg);
-+ if (cert_fail == null) {
-+ cert_fail = "did-not-fail";
-+ }
-+ return true;
-+ } else {
-+ if (cert_fail == null) {
-+ cert_fail = "cert-mismatch";
-+ }
-+ return false;
-+ }
-+ }
-+ }
-+ if (cert_fail == null) {
-+ cert_fail = "missing-certs";
-+ }
-+ return false;
-+ }
-+
-+ private void dbg(String s) {
-+ if (debug) {
-+ System.out.println(s);
-+ }
-+ }
-+
-+ private int gint(String s) {
-+ int n = -1;
-+ try {
-+ Integer I = new Integer(s);
-+ n = I.intValue();
-+ } catch (Exception ex) {
-+ return -1;
-+ }
-+ return n;
-+ }
-+
-+ /* this will do the proxy CONNECT negotiation and hook us up. */
-+
-+ private void proxy_helper(String proxyHost, int proxyPort) {
-+
-+ boolean proxy_auth = false;
-+ String proxy_auth_basic_realm = "";
-+ String hp = host + ":" + port;
-+ dbg("proxy_helper: " + proxyHost + ":" + proxyPort + " hp: " + hp);
-+
-+ /* we loop here a few times trying for the password case */
-+ for (int k=0; k < 2; k++) {
-+ dbg("proxy_in_use psocket: " + k);
-+
-+ if (proxySock != null) {
-+ try {
-+ proxySock.close();
-+ } catch (Exception e) {
-+ dbg("proxy socket is grumpy.");
-+ }
-+ }
-+
-+ proxySock = psocket(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ dbg("1-a sadly, returning a null socket");
-+ return;
-+ }
-+
-+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
-+ + "Host: " + hp + "\r\n";
-+
-+ dbg("requesting via proxy: " + req1);
-+
-+ if (proxy_auth) {
-+ if (proxy_auth_string == null) {
-+ ProxyPasswdDialog pp = new ProxyPasswdDialog(proxyHost, proxyPort, proxy_auth_basic_realm);
-+ pp.queryUser();
-+ proxy_auth_string = pp.getAuth();
-+ }
-+ //dbg("auth1: " + proxy_auth_string);
-+
-+ String auth2 = Base64Coder.encodeString(proxy_auth_string);
-+ //dbg("auth2: " + auth2);
-+
-+ req1 += "Proxy-Authorization: Basic " + auth2 + "\r\n";
-+ //dbg("req1: " + req1);
-+
-+ dbg("added Proxy-Authorization: Basic ... to request");
-+ }
-+ req1 += "\r\n";
-+
-+ try {
-+ proxy_os.write(req1.getBytes());
-+ String reply = readline(proxy_is);
-+
-+ dbg("proxy replied: " + reply.trim());
-+
-+ if (reply.indexOf("HTTP/1.") == 0 && reply.indexOf(" 407 ") > 0) {
-+ proxy_auth = true;
-+ proxySock.close();
-+ } else if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
-+ proxySock.close();
-+ proxySock = psocket(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ dbg("2-a sadly, returning a null socket");
-+ return;
-+ }
-+ }
-+ } catch(Exception e) {
-+ dbg("some proxy socket problem: " + e.getMessage());
-+ }
-+
-+ /* read the rest of the HTTP headers */
-+ while (true) {
-+ String line = readline(proxy_is);
-+ dbg("proxy line: " + line.trim());
-+ if (proxy_auth) {
-+ String uc = line.toLowerCase();
-+ if (uc.indexOf("proxy-authenticate:") == 0) {
-+ if (uc.indexOf(" basic ") >= 0) {
-+ int idx = uc.indexOf(" realm");
-+ if (idx >= 0) {
-+ proxy_auth_basic_realm = uc.substring(idx+1);
-+ }
-+ }
-+ }
-+ }
-+ if (line.equals("\r\n") || line.equals("\n")) {
-+ break;
-+ }
-+ }
-+ if (!proxy_auth || proxy_auth_basic_realm.equals("")) {
-+ /* we only try once for the non-password case: */
-+ break;
-+ }
-+ }
-+ }
-+
-+ public SSLSocket proxy_socket(SSLSocketFactory factory) {
-+ Properties props = null;
-+ String proxyHost = null;
-+ int proxyPort = 0;
-+ String proxyHost_nossl = null;
-+ int proxyPort_nossl = 0;
-+ String str;
-+
-+ /* see if we can guess the proxy info from Properties: */
-+ try {
-+ props = System.getProperties();
-+ } catch (Exception e) {
-+ /* sandboxed applet might not be able to read it. */
-+ dbg("props failed: " + e.getMessage());
-+ }
-+ if (viewer.proxyHost != null) {
-+ dbg("Using supplied proxy " + viewer.proxyHost + " " + viewer.proxyPort + " applet parameters.");
-+ proxyHost = viewer.proxyHost;
-+ if (viewer.proxyPort != null) {
-+ proxyPort = gint(viewer.proxyPort);
-+ } else {
-+ proxyPort = 8080;
-+ }
-+
-+ } else if (props != null) {
-+ dbg("\n---------------\nAll props:");
-+ props.list(System.out);
-+ dbg("\n---------------\n\n");
-+
-+ /* scrape throught properties looking for proxy info: */
-+
-+ for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
-+ String s = (String) e.nextElement();
-+ String v = System.getProperty(s);
-+ String s2 = s.toLowerCase();
-+ String v2 = v.toLowerCase();
-+
-+ if (s2.indexOf("proxy.https.host") >= 0) {
-+ proxyHost = v2;
-+ continue;
-+ }
-+ if (s2.indexOf("proxy.https.port") >= 0) {
-+ proxyPort = gint(v2);
-+ continue;
-+ }
-+ if (s2.indexOf("proxy.http.host") >= 0) {
-+ proxyHost_nossl = v2;
-+ continue;
-+ }
-+ if (s2.indexOf("proxy.http.port") >= 0) {
-+ proxyPort_nossl = gint(v2);
-+ continue;
-+ }
-+ }
-+
-+ for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
-+ String s = (String) e.nextElement();
-+ String v = System.getProperty(s);
-+ String s2 = s.toLowerCase();
-+ String v2 = v.toLowerCase();
-+
-+ if (proxyHost != null && proxyPort > 0) {
-+ break;
-+ }
-+
-+ // look for something like: javaplugin.proxy.config.list = http=10.0.2.1:8082
-+ if (s2.indexOf("proxy") < 0 && v2.indexOf("proxy") < 0) {
-+ continue;
-+ }
-+ if (v2.indexOf("http") < 0) {
-+ continue;
-+ }
-+
-+ String[] pieces = v.split("[,;]");
-+ for (int i = 0; i < pieces.length; i++) {
-+ String p = pieces[i];
-+ int j = p.indexOf("https");
-+ if (j < 0) {
-+ j = p.indexOf("http");
-+ if (j < 0) {
-+ continue;
-+ }
-+ }
-+ j = p.indexOf("=", j);
-+ if (j < 0) {
-+ continue;
-+ }
-+ p = p.substring(j+1);
-+ String [] hp = p.split(":");
-+ if (hp.length != 2) {
-+ continue;
-+ }
-+ if (hp[0].length() > 1 && hp[1].length() > 1) {
-+
-+ proxyPort = gint(hp[1]);
-+ if (proxyPort < 0) {
-+ continue;
-+ }
-+ proxyHost = new String(hp[0]);
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ if (proxyHost != null) {
-+ if (proxyHost_nossl != null && proxyPort_nossl > 0) {
-+ dbg("Using http proxy info instead of https.");
-+ proxyHost = proxyHost_nossl;
-+ proxyPort = proxyPort_nossl;
-+ }
-+ }
-+
-+ if (proxy_in_use) {
-+ if (proxy_dialog_host != null && proxy_dialog_port > 0) {
-+ proxyHost = proxy_dialog_host;
-+ proxyPort = proxy_dialog_port;
-+ }
-+ if (proxyHost != null) {
-+ dbg("Lucky us! we figured out the Proxy parameters: " + proxyHost + " " + proxyPort);
-+ } else {
-+ /* ask user to help us: */
-+ ProxyDialog pd = new ProxyDialog(proxyHost, proxyPort);
-+ pd.queryUser();
-+ proxyHost = pd.getHost();
-+ proxyPort = pd.getPort();
-+ proxy_dialog_host = new String(proxyHost);
-+ proxy_dialog_port = proxyPort;
-+ dbg("User said host: " + pd.getHost() + " port: " + pd.getPort());
-+ }
-+
-+ proxy_helper(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ return null;
-+ }
-+ } else if (viewer.CONNECT != null) {
-+ dbg("viewer.CONNECT psocket:");
-+ proxySock = psocket(host, port);
-+ if (proxySock == null) {
-+ dbg("1-b sadly, returning a null socket");
-+ return null;
-+ }
-+ }
-+
-+ if (viewer.CONNECT != null) {
-+ String hp = viewer.CONNECT;
-+ String req2 = "CONNECT " + hp + " HTTP/1.1\r\n"
-+ + "Host: " + hp + "\r\n\r\n";
-+
-+ dbg("requesting2: " + req2);
-+
-+ try {
-+ proxy_os.write(req2.getBytes());
-+ String reply = readline(proxy_is);
-+
-+ dbg("proxy replied2: " + reply.trim());
-+
-+ if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
-+ proxySock.close();
-+ proxySock = psocket(proxyHost, proxyPort);
-+ if (proxySock == null) {
-+ dbg("2-b sadly, returning a null socket");
-+ return null;
-+ }
-+ }
-+ } catch(Exception e) {
-+ dbg("proxy socket problem-2: " + e.getMessage());
-+ }
-+
-+ while (true) {
-+ String line = readline(proxy_is);
-+ dbg("proxy line2: " + line.trim());
-+ if (line.equals("\r\n") || line.equals("\n")) {
-+ break;
-+ }
-+ }
-+ }
-+
-+ Socket sslsock = null;
-+ try {
-+ sslsock = factory.createSocket(proxySock, host, port, true);
-+ } catch(Exception e) {
-+ dbg("sslsock prob: " + e.getMessage());
-+ dbg("3 sadly, returning a null socket");
-+ }
-+
-+ return (SSLSocket) sslsock;
-+ }
-+
-+ Socket psocket(String h, int p) {
-+ Socket psock = null;
-+ try {
-+ psock = new Socket(h, p);
-+ proxy_is = new DataInputStream(new BufferedInputStream(
-+ psock.getInputStream(), 16384));
-+ proxy_os = psock.getOutputStream();
-+ } catch(Exception e) {
-+ dbg("psocket prob: " + e.getMessage());
-+ return null;
-+ }
-+
-+ return psock;
-+ }
-+
-+ String readline(DataInputStream i) {
-+ byte[] ba = new byte[1];
-+ String s = new String("");
-+ ba[0] = 0;
-+ try {
-+ while (ba[0] != 0xa) {
-+ ba[0] = (byte) i.readUnsignedByte();
-+ s += new String(ba);
-+ }
-+ } catch (Exception e) {
-+ ;
-+ }
-+ return s;
-+ }
-+}
-+
-+class TrustDialog implements ActionListener {
-+ String msg, host, text;
-+ int port;
-+ java.security.cert.Certificate[] trustallCerts = null;
-+ boolean viewing_cert = false;
-+ boolean trust_this_session = false;
-+
-+ /*
-+ * this is the gui to show the user the cert and info and ask
-+ * them if they want to continue using this cert.
-+ */
-+
-+ Button ok, cancel, viewcert;
-+ TextArea textarea;
-+ Checkbox accept, deny;
-+ Dialog dialog;
-+
-+ String s1 = "Accept this certificate temporarily for this session";
-+ String s2 = "Do not accept this certificate and do not connect to"
-+ + " this VNC server";
-+ String ln = "\n---------------------------------------------------\n\n";
-+
-+ TrustDialog (String h, int p, java.security.cert.Certificate[] s) {
-+ host = h;
-+ port = p;
-+ trustallCerts = s;
-+
-+ msg = "VNC Server " + host + ":" + port + " Not Verified";
-+ }
-+
-+ public boolean queryUser(String reason) {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame(msg);
-+
-+ dialog = new Dialog(frame, true);
-+
-+ String infostr = "";
-+ if (trustallCerts.length == 1) {
-+ CertInfo ci = new CertInfo(trustallCerts[0]);
-+ infostr = ci.get_certinfo("all");
-+ }
-+ if (reason != null) {
-+ reason += "\n\n";
-+ }
-+
-+ text = "\n"
-++ "Unable to verify the identity of\n"
-++ "\n"
-++ " " + host + ":" + port + "\n"
-++ "\n"
-++ infostr
-++ "\n"
-++ "as a trusted VNC server.\n"
-++ "\n"
-++ reason
-++ "In General not being able to verify the VNC Server and/or your seeing this Dialog\n"
-++ "is due to one of the following:\n"
-++ "\n"
-++ " - Your requesting to View the Certificate before accepting.\n"
-++ "\n"
-++ " - The VNC server is using a Self-Signed Certificate or a Certificate\n"
-++ " Authority not recognized by your Web Browser or Java Plugin runtime.\n"
-++ "\n"
-++ " - The use of an Apache SSL portal scheme employing CONNECT proxying AND\n"
-++ " the Apache Web server has a certificate *different* from the VNC server's.\n"
-++ "\n"
-++ " - No previously accepted Certificate (via Web Broswer/Java Plugin) could be\n"
-++ " obtained by this applet to compare the VNC Server Certificate against.\n"
-++ "\n"
-++ " - The VNC Server's Certificate does not match the one specified in the\n"
-++ " supplied 'serverCert' Java Applet Parameter.\n"
-++ "\n"
-++ " - A Man-In-The-Middle attack impersonating as the VNC server that you wish\n"
-++ " to connect to. (Wouldn't that be exciting!!)\n"
-++ "\n"
-++ "By safely copying the VNC server's Certificate (or using a common Certificate\n"
-++ "Authority certificate) you can configure your Web Browser and Java Plugin to\n"
-++ "automatically authenticate this VNC Server.\n"
-++ "\n"
-++ "If you do so, then you will only have to click \"Yes\" when this VNC Viewer\n"
-++ "applet asks you whether to trust your Browser/Java Plugin's acceptance of the\n"
-++ "certificate (except for the Apache portal case above where they don't match.)\n"
-++ "\n"
-++ "You can also set the applet parameter 'trustUrlVncCert=yes' to automatically\n"
-++ "accept certificates already accepted/trusted by your Web Browser/Java Plugin,\n"
-++ "and thereby see no dialog from this VNC Viewer applet.\n"
-+;
-+
-+ /* the accept / do-not-accept radio buttons: */
-+ CheckboxGroup checkbox = new CheckboxGroup();
-+ accept = new Checkbox(s1, true, checkbox);
-+ deny = new Checkbox(s2, false, checkbox);
-+
-+ /* put the checkboxes in a panel: */
-+ Panel check = new Panel();
-+ check.setLayout(new GridLayout(2, 1));
-+
-+ check.add(accept);
-+ check.add(deny);
-+
-+ /* make the 3 buttons: */
-+ ok = new Button("OK");
-+ cancel = new Button("Cancel");
-+ viewcert = new Button("View Certificate");
-+
-+ ok.addActionListener(this);
-+ cancel.addActionListener(this);
-+ viewcert.addActionListener(this);
-+
-+ /* put the buttons in their own panel: */
-+ Panel buttonrow = new Panel();
-+ buttonrow.setLayout(new FlowLayout(FlowLayout.LEFT));
-+ buttonrow.add(viewcert);
-+ buttonrow.add(ok);
-+ buttonrow.add(cancel);
-+
-+ /* label at the top: */
-+ Label label = new Label(msg, Label.CENTER);
-+ label.setFont(new Font("Helvetica", Font.BOLD, 16));
-+
-+ /* textarea in the middle */
-+ textarea = new TextArea(text, 38, 64,
-+ TextArea.SCROLLBARS_VERTICAL_ONLY);
-+ textarea.setEditable(false);
-+
-+ /* put the two panels in their own panel at bottom: */
-+ Panel bot = new Panel();
-+ bot.setLayout(new GridLayout(2, 1));
-+ bot.add(check);
-+ bot.add(buttonrow);
-+
-+ /* now arrange things inside the dialog: */
-+ dialog.setLayout(new BorderLayout());
-+
-+ dialog.add("North", label);
-+ dialog.add("South", bot);
-+ dialog.add("Center", textarea);
-+
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+
-+ return trust_this_session;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+
-+ if (evt.getSource() == viewcert) {
-+ /* View Certificate button clicked */
-+ if (viewing_cert) {
-+ /* show the original info text: */
-+ textarea.setText(text);
-+ viewcert.setLabel("View Certificate");
-+ viewing_cert = false;
-+ } else {
-+ int i;
-+ /* show all (likely just one) certs: */
-+ textarea.setText("");
-+ for (i=0; i < trustallCerts.length; i++) {
-+ int j = i + 1;
-+ textarea.append("Certificate[" +
-+ j + "]\n\n");
-+ textarea.append(
-+ trustallCerts[i].toString());
-+ textarea.append(ln);
-+ }
-+ viewcert.setLabel("View Info");
-+ viewing_cert = true;
-+
-+ textarea.setCaretPosition(0);
-+ }
-+
-+ } else if (evt.getSource() == ok) {
-+ /* OK button clicked */
-+ if (accept.getState()) {
-+ trust_this_session = true;
-+ } else {
-+ trust_this_session = false;
-+ }
-+ //dialog.dispose();
-+ dialog.hide();
-+
-+ } else if (evt.getSource() == cancel) {
-+ /* Cancel button clicked */
-+ trust_this_session = false;
-+
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+
-+ String get_certinfo() {
-+ String all = "";
-+ String fields[] = {"CN", "OU", "O", "L", "C"};
-+ int i;
-+ if (trustallCerts.length < 1) {
-+ all = "";
-+ return all;
-+ }
-+ String cert = trustallCerts[0].toString();
-+
-+ /*
-+ * For now we simply scrape the cert string, there must
-+ * be an API for this... perhaps optionValue?
-+ */
-+
-+ for (i=0; i < fields.length; i++) {
-+ int f, t, t1, t2;
-+ String sub, mat = fields[i] + "=";
-+
-+ f = cert.indexOf(mat, 0);
-+ if (f > 0) {
-+ t1 = cert.indexOf(", ", f);
-+ t2 = cert.indexOf("\n", f);
-+ if (t1 < 0 && t2 < 0) {
-+ continue;
-+ } else if (t1 < 0) {
-+ t = t2;
-+ } else if (t2 < 0) {
-+ t = t1;
-+ } else if (t1 < t2) {
-+ t = t1;
-+ } else {
-+ t = t2;
-+ }
-+ if (t > f) {
-+ sub = cert.substring(f, t);
-+ all = all + " " + sub + "\n";
-+ }
-+ }
-+ }
-+ return all;
-+ }
-+}
-+
-+class ProxyDialog implements ActionListener {
-+ String guessedHost = null;
-+ String guessedPort = null;
-+ /*
-+ * this is the gui to show the user the cert and info and ask
-+ * them if they want to continue using this cert.
-+ */
-+
-+ Button ok;
-+ Dialog dialog;
-+ TextField entry;
-+ String reply = "";
-+
-+ ProxyDialog (String h, int p) {
-+ guessedHost = h;
-+ try {
-+ guessedPort = Integer.toString(p);
-+ } catch (Exception e) {
-+ guessedPort = "8080";
-+ }
-+ }
-+
-+ public void queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Need Proxy host:port");
-+
-+ dialog = new Dialog(frame, true);
-+
-+
-+ Label label = new Label("Please Enter your https Proxy info as host:port", Label.CENTER);
-+ //label.setFont(new Font("Helvetica", Font.BOLD, 16));
-+ entry = new TextField(30);
-+ ok = new Button("OK");
-+ ok.addActionListener(this);
-+
-+ String guess = "";
-+ if (guessedHost != null) {
-+ guess = guessedHost + ":" + guessedPort;
-+ }
-+ entry.setText(guess);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", label);
-+ dialog.add("Center", entry);
-+ dialog.add("South", ok);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+ return;
-+ }
-+
-+ public String getHost() {
-+ int i = reply.indexOf(":");
-+ if (i < 0) {
-+ return "unknown";
-+ }
-+ String h = reply.substring(0, i);
-+ return h;
-+ }
-+
-+ public int getPort() {
-+ int i = reply.indexOf(":");
-+ int p = 8080;
-+ if (i < 0) {
-+ return p;
-+ }
-+ i++;
-+ String ps = reply.substring(i);
-+ try {
-+ Integer I = new Integer(ps);
-+ p = I.intValue();
-+ } catch (Exception e) {
-+ ;
-+ }
-+ return p;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == ok) {
-+ reply = entry.getText();
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+}
-+
-+class ProxyPasswdDialog implements ActionListener {
-+ String guessedHost = null;
-+ String guessedPort = null;
-+ String guessedUser = null;
-+ String guessedPasswd = null;
-+ String realm = null;
-+ /*
-+ * this is the gui to show the user the cert and info and ask
-+ * them if they want to continue using this cert.
-+ */
-+
-+ Button ok;
-+ Dialog dialog;
-+ TextField entry1;
-+ TextField entry2;
-+ String reply1 = "";
-+ String reply2 = "";
-+
-+ ProxyPasswdDialog (String h, int p, String realm) {
-+ guessedHost = h;
-+ try {
-+ guessedPort = Integer.toString(p);
-+ } catch (Exception e) {
-+ guessedPort = "8080";
-+ }
-+ this.realm = realm;
-+ }
-+
-+ public void queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Proxy Requires Username and Password");
-+
-+ dialog = new Dialog(frame, true);
-+
-+ //Label label = new Label("Please Enter your Web Proxy Username in the top Entry and Password in the bottom Entry", Label.CENTER);
-+ TextArea label = new TextArea("Please Enter your Web Proxy\nUsername in the Top Entry and\nPassword in the Bottom Entry,\nand then press OK.", 4, 20, TextArea.SCROLLBARS_NONE);
-+ entry1 = new TextField(30);
-+ entry2 = new TextField(30);
-+ entry2.setEchoChar('*');
-+ ok = new Button("OK");
-+ ok.addActionListener(this);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", label);
-+ dialog.add("Center", entry1);
-+ dialog.add("South", entry2);
-+ dialog.add("East", ok);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+ return;
-+ }
-+
-+ public String getAuth() {
-+ return reply1 + ":" + reply2;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == ok) {
-+ reply1 = entry1.getText();
-+ reply2 = entry2.getText();
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+}
-+
-+class ClientCertDialog implements ActionListener {
-+
-+ Button ok;
-+ Dialog dialog;
-+ TextField entry;
-+ String reply = "";
-+
-+ ClientCertDialog() {
-+ ;
-+ }
-+
-+ public String queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Enter SSL Client Cert+Key String");
-+
-+ dialog = new Dialog(frame, true);
-+
-+
-+ Label label = new Label("Please Enter the SSL Client Cert+Key String 308204c0...,...522d2d0a", Label.CENTER);
-+ entry = new TextField(30);
-+ ok = new Button("OK");
-+ ok.addActionListener(this);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", label);
-+ dialog.add("Center", entry);
-+ dialog.add("South", ok);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til OK or Cancel pressed. */
-+ return reply;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == ok) {
-+ reply = entry.getText();
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ }
-+}
-+
-+class BrowserCertsDialog implements ActionListener {
-+ Button yes, no;
-+ Dialog dialog;
-+ String vncServer;
-+ String hostport;
-+ public boolean showCertDialog = true;
-+
-+ BrowserCertsDialog(String serv, String hp) {
-+ vncServer = serv;
-+ hostport = hp;
-+ }
-+
-+ public void queryUser() {
-+
-+ /* create and display the dialog for unverified cert. */
-+
-+ Frame frame = new Frame("Use Browser/JVM Certs?");
-+
-+ dialog = new Dialog(frame, true);
-+
-+ String m = "";
-+m += "\n";
-+m += "This VNC Viewer applet does not have its own keystore to track\n";
-+m += "SSL certificates, and so cannot authenticate the certificate\n";
-+m += "of the VNC Server:\n";
-+m += "\n";
-+m += " " + hostport + "\n\n " + vncServer + "\n";
-+m += "\n";
-+m += "on its own.\n";
-+m += "\n";
-+m += "However, it has noticed that your Web Browser and/or Java VM Plugin\n";
-+m += "has previously accepted the same certificate. You may have set\n";
-+m += "this up permanently or just for this session, or the server\n";
-+m += "certificate was signed by a CA cert that your Web Browser or\n";
-+m += "Java VM Plugin has.\n";
-+m += "\n";
-+m += "If the VNC Server connection times out while you are reading this\n";
-+m += "dialog, then restart the connection and try again.\n";
-+m += "\n";
-+m += "Should this VNC Viewer applet now connect to the above VNC server?\n";
-+m += "\n";
-+
-+ TextArea textarea = new TextArea(m, 22, 64,
-+ TextArea.SCROLLBARS_VERTICAL_ONLY);
-+ textarea.setEditable(false);
-+ yes = new Button("Yes");
-+ yes.addActionListener(this);
-+ no = new Button("No, Let Me See the Certificate.");
-+ no.addActionListener(this);
-+
-+ dialog.setLayout(new BorderLayout());
-+ dialog.add("North", textarea);
-+ dialog.add("Center", yes);
-+ dialog.add("South", no);
-+ dialog.pack();
-+ dialog.resize(dialog.preferredSize());
-+
-+ dialog.show(); /* block here til Yes or No pressed. */
-+ System.out.println("done show()");
-+ return;
-+ }
-+
-+ public synchronized void actionPerformed(ActionEvent evt) {
-+ System.out.println(evt.getActionCommand());
-+ if (evt.getSource() == yes) {
-+ showCertDialog = false;
-+ //dialog.dispose();
-+ dialog.hide();
-+ } else if (evt.getSource() == no) {
-+ showCertDialog = true;
-+ //dialog.dispose();
-+ dialog.hide();
-+ }
-+ System.out.println("done actionPerformed()");
-+ }
-+}
-+
-+class CertInfo {
-+ String fields[] = {"CN", "OU", "O", "L", "C"};
-+ java.security.cert.Certificate cert;
-+ String certString = "";
-+
-+ CertInfo(java.security.cert.Certificate c) {
-+ cert = c;
-+ certString = cert.toString();
-+ }
-+
-+ String get_certinfo(String which) {
-+ int i;
-+ String cs = new String(certString);
-+ String all = "";
-+
-+ /*
-+ * For now we simply scrape the cert string, there must
-+ * be an API for this... perhaps optionValue?
-+ */
-+ for (i=0; i < fields.length; i++) {
-+ int f, t, t1, t2;
-+ String sub, mat = fields[i] + "=";
-+
-+ f = cs.indexOf(mat, 0);
-+ if (f > 0) {
-+ t1 = cs.indexOf(", ", f);
-+ t2 = cs.indexOf("\n", f);
-+ if (t1 < 0 && t2 < 0) {
-+ continue;
-+ } else if (t1 < 0) {
-+ t = t2;
-+ } else if (t2 < 0) {
-+ t = t1;
-+ } else if (t1 < t2) {
-+ t = t1;
-+ } else {
-+ t = t2;
-+ }
-+ if (t > f) {
-+ sub = cs.substring(f, t);
-+ all = all + " " + sub + "\n";
-+ if (which.equals(fields[i])) {
-+ return sub;
-+ }
-+ }
-+ }
-+ }
-+ if (which.equals("all")) {
-+ return all;
-+ } else {
-+ return "";
-+ }
-+ }
-+}
-+
-+class Base64Coder {
-+
-+ // Mapping table from 6-bit nibbles to Base64 characters.
-+ private static char[] map1 = new char[64];
-+ static {
-+ int i=0;
-+ for (char c='A'; c<='Z'; c++) map1[i++] = c;
-+ for (char c='a'; c<='z'; c++) map1[i++] = c;
-+ for (char c='0'; c<='9'; c++) map1[i++] = c;
-+ map1[i++] = '+'; map1[i++] = '/'; }
-+
-+ // Mapping table from Base64 characters to 6-bit nibbles.
-+ private static byte[] map2 = new byte[128];
-+ static {
-+ for (int i=0; i<map2.length; i++) map2[i] = -1;
-+ for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
-+
-+ /**
-+ * Encodes a string into Base64 format.
-+ * No blanks or line breaks are inserted.
-+ * @param s a String to be encoded.
-+ * @return A String with the Base64 encoded data.
-+ */
-+ public static String encodeString (String s) {
-+ return new String(encode(s.getBytes())); }
-+
-+ /**
-+ * Encodes a byte array into Base64 format.
-+ * No blanks or line breaks are inserted.
-+ * @param in an array containing the data bytes to be encoded.
-+ * @return A character array with the Base64 encoded data.
-+ */
-+ public static char[] encode (byte[] in) {
-+ return encode(in,in.length); }
-+
-+ /**
-+ * Encodes a byte array into Base64 format.
-+ * No blanks or line breaks are inserted.
-+ * @param in an array containing the data bytes to be encoded.
-+ * @param iLen number of bytes to process in <code>in</code>.
-+ * @return A character array with the Base64 encoded data.
-+ */
-+ public static char[] encode (byte[] in, int iLen) {
-+ int oDataLen = (iLen*4+2)/3; // output length without padding
-+ int oLen = ((iLen+2)/3)*4; // output length including padding
-+ char[] out = new char[oLen];
-+ int ip = 0;
-+ int op = 0;
-+ while (ip < iLen) {
-+ int i0 = in[ip++] & 0xff;
-+ int i1 = ip < iLen ? in[ip++] & 0xff : 0;
-+ int i2 = ip < iLen ? in[ip++] & 0xff : 0;
-+ int o0 = i0 >>> 2;
-+ int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
-+ int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
-+ int o3 = i2 & 0x3F;
-+ out[op++] = map1[o0];
-+ out[op++] = map1[o1];
-+ out[op] = op < oDataLen ? map1[o2] : '='; op++;
-+ out[op] = op < oDataLen ? map1[o3] : '='; op++; }
-+ return out; }
-+
-+ /**
-+ * Decodes a string from Base64 format.
-+ * @param s a Base64 String to be decoded.
-+ * @return A String containing the decoded data.
-+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
-+ */
-+ public static String decodeString (String s) {
-+ return new String(decode(s)); }
-+
-+ /**
-+ * Decodes a byte array from Base64 format.
-+ * @param s a Base64 String to be decoded.
-+ * @return An array containing the decoded data bytes.
-+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
-+ */
-+ public static byte[] decode (String s) {
-+ return decode(s.toCharArray()); }
-+
-+ /**
-+ * Decodes a byte array from Base64 format.
-+ * No blanks or line breaks are allowed within the Base64 encoded data.
-+ * @param in a character array containing the Base64 encoded data.
-+ * @return An array containing the decoded data bytes.
-+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
-+ */
-+ public static byte[] decode (char[] in) {
-+ int iLen = in.length;
-+ if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
-+ while (iLen > 0 && in[iLen-1] == '=') iLen--;
-+ int oLen = (iLen*3) / 4;
-+ byte[] out = new byte[oLen];
-+ int ip = 0;
-+ int op = 0;
-+ while (ip < iLen) {
-+ int i0 = in[ip++];
-+ int i1 = in[ip++];
-+ int i2 = ip < iLen ? in[ip++] : 'A';
-+ int i3 = ip < iLen ? in[ip++] : 'A';
-+ if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
-+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
-+ int b0 = map2[i0];
-+ int b1 = map2[i1];
-+ int b2 = map2[i2];
-+ int b3 = map2[i3];
-+ if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
-+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
-+ int o0 = ( b0 <<2) | (b1>>>4);
-+ int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
-+ int o2 = ((b2 & 3)<<6) | b3;
-+ out[op++] = (byte)o0;
-+ if (op<oLen) out[op++] = (byte)o1;
-+ if (op<oLen) out[op++] = (byte)o2; }
-+ return out; }
-+
-+ // Dummy constructor.
-+ private Base64Coder() {}
-+
-+}
-diff -Naur JavaViewer.orig/VncCanvas.java JavaViewer/VncCanvas.java
---- JavaViewer.orig/VncCanvas.java 2005-11-21 18:50:18.000000000 -0500
-+++ JavaViewer/VncCanvas.java 2010-11-30 22:57:50.000000000 -0500
-@@ -27,6 +27,13 @@
- import java.lang.*;
- import java.util.zip.*;
-
-+// begin runge/x11vnc
-+import java.util.Collections;
-+// end runge/x11vnc
-+
-+// begin runge/x11vnc
-+// all the MouseWheel stuff below.
-+// end runge/x11vnc
-
- //
- // VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
-@@ -34,7 +41,7 @@
-
- class VncCanvas
- extends Canvas
-- implements KeyListener, MouseListener, MouseMotionListener {
-+ implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {
-
- VncViewer viewer;
- RfbProto rfb;
-@@ -85,6 +92,22 @@
-
- cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
-
-+// begin runge/x11vnc
-+// kludge to not show any Java cursor in the canvas since we are
-+// showing the soft cursor (should be a user setting...)
-+Cursor dot = Toolkit.getDefaultToolkit().createCustomCursor(
-+ Toolkit.getDefaultToolkit().createImage(new byte[4]), new Point(0,0),
-+ "dot");
-+this.setCursor(dot);
-+
-+// while we are at it... get rid of the keyboard traversals that
-+// make it so we can't type a Tab character:
-+this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
-+ Collections.EMPTY_SET);
-+this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
-+ Collections.EMPTY_SET);
-+// end runge/x11vnc
-+
- colors = new Color[256];
- // sf@2005 - Now Default
- for (int i = 0; i < 256; i++)
-@@ -186,6 +209,7 @@
- inputEnabled = true;
- addMouseListener(this);
- addMouseMotionListener(this);
-+ addMouseWheelListener(this);
- if (viewer.showControls) {
- viewer.buttonPanel.enableRemoteAccessControls(true);
- }
-@@ -193,6 +217,7 @@
- inputEnabled = false;
- removeMouseListener(this);
- removeMouseMotionListener(this);
-+ removeMouseWheelListener(this);
- if (viewer.showControls) {
- viewer.buttonPanel.enableRemoteAccessControls(false);
- }
-@@ -202,6 +227,9 @@
-
- public void setPixelFormat() throws IOException {
- // sf@2005 - Adding more color modes
-+ if (viewer.graftFtp) {
-+ return;
-+ }
- if (viewer.options.eightBitColors > 0)
- {
- viewer.options.oldEightBitColors = viewer.options.eightBitColors;
-@@ -237,6 +265,9 @@
- }
- else
- {
-+// begin runge/x11vnc
-+ viewer.options.oldEightBitColors = viewer.options.eightBitColors;
-+// end runge/x11vnc
- rfb.writeSetPixelFormat(
- 32,
- 24,
-@@ -376,12 +407,14 @@
- // Start/stop session recording if necessary.
- viewer.checkRecordingStatus();
-
-- rfb.writeFramebufferUpdateRequest(
-- 0,
-- 0,
-- rfb.framebufferWidth,
-- rfb.framebufferHeight,
-- false);
-+ if (!viewer.graftFtp) {
-+ rfb.writeFramebufferUpdateRequest(
-+ 0,
-+ 0,
-+ rfb.framebufferWidth,
-+ rfb.framebufferHeight,
-+ false);
-+ }
-
- //
- // main dispatch loop
-@@ -390,6 +423,9 @@
- while (true) {
- // Read message type from the server.
- int msgType = rfb.readServerMessageType();
-+ if (viewer.ftpOnly && msgType != RfbProto.rfbFileTransfer) {
-+ System.out.println("msgType:" + msgType);
-+ }
-
- // Process the message depending on its type.
- switch (msgType) {
-@@ -1332,6 +1368,9 @@
- public void mouseDragged(MouseEvent evt) {
- processLocalMouseEvent(evt, true);
- }
-+ public void mouseWheelMoved(MouseWheelEvent evt) {
-+ processLocalMouseWheelEvent(evt);
-+ }
-
- public void processLocalKeyEvent(KeyEvent evt) {
- if (viewer.rfb != null && rfb.inNormalProtocol) {
-@@ -1367,6 +1406,19 @@
- evt.consume();
- }
-
-+ public void processLocalMouseWheelEvent(MouseWheelEvent evt) {
-+ if (viewer.rfb != null && rfb.inNormalProtocol) {
-+ synchronized(rfb) {
-+ try {
-+ rfb.writeWheelEvent(evt);
-+ } catch (Exception e) {
-+ e.printStackTrace();
-+ }
-+ rfb.notify();
-+ }
-+ }
-+ }
-+
- public void processLocalMouseEvent(MouseEvent evt, boolean moved) {
- if (viewer.rfb != null && rfb.inNormalProtocol) {
- if (moved) {
-@@ -1532,9 +1584,14 @@
- else
- {
- result =
-- 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
-- << 16 | (pixBuf[i * 4 + 2] & 0xFF)
-- << 8 | (pixBuf[i * 4 + 3] & 0xFF);
-+// begin runge/x11vnc
-+// 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
-+// << 16 | (pixBuf[i * 4 + 2] & 0xFF)
-+// << 8 | (pixBuf[i * 4 + 3] & 0xFF);
-+ 0xFF000000 | (pixBuf[i * 4 + 2] & 0xFF)
-+ << 16 | (pixBuf[i * 4 + 1] & 0xFF)
-+ << 8 | (pixBuf[i * 4 + 0] & 0xFF);
-+// end runge/x11vnc
- }
- } else {
- result = 0; // Transparent pixel
-@@ -1565,9 +1622,14 @@
- else
- {
- result =
-- 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
-- << 16 | (pixBuf[i * 4 + 2] & 0xFF)
-- << 8 | (pixBuf[i * 4 + 3] & 0xFF);
-+// begin runge/x11vnc
-+// 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
-+// << 16 | (pixBuf[i * 4 + 2] & 0xFF)
-+// << 8 | (pixBuf[i * 4 + 3] & 0xFF);
-+ 0xFF000000 | (pixBuf[i * 4 + 2] & 0xFF)
-+ << 16 | (pixBuf[i * 4 + 1] & 0xFF)
-+ << 8 | (pixBuf[i * 4 + 0] & 0xFF);
-+// end runge/x11vnc
- }
- } else {
- result = 0; // Transparent pixel
-diff -Naur JavaViewer.orig/VncViewer.java JavaViewer/VncViewer.java
---- JavaViewer.orig/VncViewer.java 2006-05-24 15:14:40.000000000 -0400
-+++ JavaViewer/VncViewer.java 2010-03-27 18:00:28.000000000 -0400
-@@ -41,6 +41,7 @@
- import java.io.*;
- import java.net.*;
- import javax.swing.*;
-+import java.util.Date;
-
- public class VncViewer extends java.applet.Applet
- implements java.lang.Runnable, WindowListener {
-@@ -80,11 +81,11 @@
- GridBagLayout gridbag;
- ButtonPanel buttonPanel;
- AuthPanel authenticator;
-- VncCanvas vc;
-+ VncCanvas vc = null;
- OptionsFrame options;
- ClipboardFrame clipboard;
- RecordingFrame rec;
-- FTPFrame ftp; // KMC: FTP Frame declaration
-+ FTPFrame ftp = null; // KMC: FTP Frame declaration
-
- // Control session recording.
- Object recordingSync;
-@@ -96,7 +97,7 @@
-
- // Variables read from parameter values.
- String host;
-- int port;
-+ int port, vncserverport;
- String passwordParam;
- String encPasswordParam;
- boolean showControls;
-@@ -115,28 +116,75 @@
- int i;
- // mslogon support 2 end
-
-+// begin runge/x11vnc
-+boolean disableSSL;
-+boolean GET;
-+String CONNECT;
-+String urlPrefix;
-+String httpsPort;
-+String oneTimeKey;
-+String serverCert;
-+String ftpDropDown;
-+String proxyHost;
-+String proxyPort;
-+boolean forceProxy;
-+boolean ignoreProxy;
-+boolean trustAllVncCerts;
-+boolean trustUrlVncCert;
-+boolean debugCerts;
-+boolean debugKeyboard;
-+boolean mapF5_to_atsign;
-+boolean forbid_Ctrl_Alt;
-+
-+boolean ignoreMSLogonCheck;
-+boolean delayAuthPanel;
-+boolean ftpOnly;
-+boolean graftFtp;
-+boolean dsmActive;
-+
-+boolean gotAuth;
-+int authGot;
-+// end runge/x11vnc
-+
-+
- //
- // init()
- //
-
-+public void ftp_init() {
-+ boolean show = false;
-+ if (ftp != null) {
-+ show = true;
-+ }
-+ ftp = null;
-+
-+ ftp = new FTPFrame(this); // KMC: FTPFrame creation
-+
-+ if (show) {
-+ ftp.doOpen();
-+ rfb.readServerDriveList();
-+ }
-+}
-+
- public void init() {
-
- readParameters();
-
- if (inSeparateFrame) {
-- vncFrame = new Frame("Ultr@VNC");
-- if (!inAnApplet) {
-- vncFrame.add("Center", this);
-- }
-- vncContainer = vncFrame;
-+ vncFrame = new Frame("Ultr@VNC");
-+ if (!inAnApplet) {
-+ vncFrame.add("Center", this);
-+ }
-+ vncContainer = vncFrame;
- } else {
-- vncContainer = this;
-+ vncContainer = this;
- }
-
- recordingSync = new Object();
-
- options = new OptionsFrame(this);
- clipboard = new ClipboardFrame(this);
-+
- // authenticator = new AuthPanel(false); // mslogon support : go to connectAndAuthenticate()
- if (RecordingFrame.checkSecurity())
- rec = new RecordingFrame(this);
-@@ -147,10 +195,11 @@
- cursorUpdatesDef = null;
- eightBitColorsDef = null;
-
-- if (inSeparateFrame)
-+ if (inSeparateFrame && vncFrame != null)
- vncFrame.addWindowListener(this);
-
-- ftp = new FTPFrame(this); // KMC: FTPFrame creation
-+ ftp_init();
-+
- rfbThread = new Thread(this);
- rfbThread.start();
- }
-@@ -186,6 +235,30 @@
- gbc.weightx = 1.0;
- gbc.weighty = 1.0;
-
-+ if (ftpOnly) {
-+ if (showControls) {
-+ buttonPanel.enableButtons();
-+ }
-+ ActionListener taskPerformer = new ActionListener() {
-+ public void actionPerformed(ActionEvent evt) {
-+ vncFrame.setVisible(false);
-+ ftp.setSavedLocations();
-+ if (ftp.isVisible()) {
-+ ftp.doClose();
-+ } else {
-+ ftp.doOpen();
-+ }
-+ rfb.readServerDriveList();
-+ }
-+ };
-+ Timer t = new Timer(300, taskPerformer);
-+ t.setRepeats(false);
-+ t.start();
-+
-+ vc.processNormalProtocol();
-+ return;
-+ }
-+
- // Add ScrollPanel to applet mode
-
- // Create a panel which itself is resizeable and can hold
-@@ -286,6 +359,24 @@
-
- void connectAndAuthenticate() throws Exception {
-
-+ if (graftFtp) {
-+ rfb = new RfbProto(host, port, this);
-+ rfb.desktopName = "ftponly";
-+ rfb.framebufferWidth = 12;
-+ rfb.framebufferHeight = 12;
-+ rfb.bitsPerPixel = 32;
-+ rfb.depth = 24;
-+ rfb.trueColour = true;
-+ rfb.redMax = 255;
-+ rfb.greenMax = 255;
-+ rfb.blueMax = 255;
-+ rfb.redShift = 16;
-+ rfb.greenShift = 8;
-+ rfb.blueShift = 0;
-+ rfb.inNormalProtocol = true;
-+ return;
-+ }
-+
- // If "ENCPASSWORD" parameter is set, decrypt the password into
- // the passwordParam string.
-
-@@ -336,7 +427,22 @@
- //
-
-
-- prologueDetectAuthProtocol() ;
-+// begin runge/x11vnc
-+ gotAuth = false;
-+ if (delayAuthPanel) {
-+ if (tryAuthenticate(null, null)) {
-+ if (inSeparateFrame) {
-+ vncFrame.pack();
-+ vncFrame.show();
-+ }
-+ return;
-+ }
-+ }
-+// prologueDetectAuthProtocol() ;
-+ if (ignoreMSLogonCheck == false) {
-+ prologueDetectAuthProtocol() ;
-+ }
-+// end runge/x11vnc
-
- authenticator = new AuthPanel(mslogon);
-
-@@ -371,6 +477,7 @@
- //mslogon support end
- }
-
-+ int tries = 0;
- while (true) {
- // Wait for user entering a password, or a username and a password
- synchronized(authenticator) {
-@@ -390,6 +497,13 @@
- break;
- //mslogon support end
-
-+// begin runge/x11vnc
-+ gotAuth = false;
-+ if (++tries > 2) {
-+ throw new Exception("Incorrect password entered " + tries + " times.");
-+ }
-+// end runge/x11vnc
-+
- // Retry on authentication failure.
- authenticator.retry();
- }
-@@ -405,9 +519,11 @@
-
- void prologueDetectAuthProtocol() throws Exception {
-
-- rfb = new RfbProto(host, port, this);
-+ if (!gotAuth) {
-+ rfb = new RfbProto(host, port, this);
-
-- rfb.readVersionMsg();
-+ rfb.readVersionMsg();
-+ }
-
- System.out.println("RFB server supports protocol version " +
- rfb.serverMajor + "." + rfb.serverMinor);
-@@ -431,16 +547,36 @@
-
- boolean tryAuthenticate(String us, String pw) throws Exception {
-
-- rfb = new RfbProto(host, port, this);
-+ int authScheme;
-
-- rfb.readVersionMsg();
-+ if (!gotAuth) {
-+ rfb = new RfbProto(host, port, this);
-
-- System.out.println("RFB server supports protocol version " +
-- rfb.serverMajor + "." + rfb.serverMinor);
-+ rfb.readVersionMsg();
-
-- rfb.writeVersionMsg();
-+ System.out.println("RFB server supports protocol version: " +
-+ rfb.serverMajor + "." + rfb.serverMinor);
-
-- int authScheme = rfb.readAuthScheme();
-+ rfb.writeVersionMsg();
-+
-+ authScheme = rfb.readAuthScheme();
-+
-+ gotAuth = true;
-+ authGot = authScheme;
-+ } else {
-+ authScheme = authGot;
-+ }
-+// begin runge/x11vnc
-+ if (delayAuthPanel && pw == null) {
-+ if (authScheme == RfbProto.NoAuth) {
-+ System.out.println("No authentication needed");
-+ return true;
-+ } else {
-+ return false;
-+ }
-+ }
-+System.out.println("as: " + authScheme);
-+// end runge/x11vnc
-
- switch (authScheme) {
-
-@@ -629,6 +765,10 @@
-
- void doProtocolInitialisation() throws IOException {
-
-+ if (graftFtp) {
-+ return;
-+ }
-+
- rfb.writeClientInit();
-
- rfb.readServerInit();
-@@ -774,9 +914,28 @@
- fatalError("HOST parameter not specified");
- }
- }
-+ Date d = new Date();
-+ System.out.println("-\nSSL VNC Java Applet starting. " + d);
-
-- String str = readParameter("PORT", true);
-- port = Integer.parseInt(str);
-+ port = 0;
-+ String str = readParameter("PORT", false);
-+ if (str != null) {
-+ port = Integer.parseInt(str);
-+ }
-+ // When there is a proxy VNCSERVERPORT may be inaccessible (inside firewall).
-+ vncserverport = 0;
-+ str = readParameter("VNCSERVERPORT", false);
-+ if (str != null) {
-+ vncserverport = Integer.parseInt(str);
-+ }
-+ if (port == 0 && vncserverport == 0) {
-+ fatalError("Neither PORT nor VNCSERVERPORT parameters specified");
-+ }
-+ if (port == 0) {
-+ // Nevertheless, fall back to vncserverport if we have to.
-+ System.out.println("using vncserverport: '" + vncserverport + "' for PORT.");
-+ port = vncserverport;
-+ }
-
- if (inAnApplet) {
- str = readParameter("Open New Window", false);
-@@ -804,6 +963,158 @@
- deferScreenUpdates = readIntParameter("Defer screen updates", 20);
- deferCursorUpdates = readIntParameter("Defer cursor updates", 10);
- deferUpdateRequests = readIntParameter("Defer update requests", 50);
-+
-+// begin runge/x11vnc
-+ // SSL
-+ disableSSL = false;
-+ str = readParameter("DisableSSL", false);
-+ if (str != null && str.equalsIgnoreCase("Yes"))
-+ disableSSL = true;
-+
-+ httpsPort = readParameter("httpsPort", false);
-+
-+ // Extra GET, CONNECT string:
-+ CONNECT = readParameter("CONNECT", false);
-+ if (CONNECT != null) {
-+ CONNECT = CONNECT.replaceAll(" ", ":");
-+ }
-+
-+ GET = false;
-+ str = readParameter("GET", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ GET = true;
-+ }
-+ if (str != null && str.equalsIgnoreCase("1")) {
-+ GET = true;
-+ }
-+
-+ urlPrefix = readParameter("urlPrefix", false);
-+ if (urlPrefix != null) {
-+ urlPrefix = urlPrefix.replaceAll("%2F", "/");
-+ urlPrefix = urlPrefix.replaceAll("%2f", "/");
-+ urlPrefix = urlPrefix.replaceAll("_2F_", "/");
-+ if (urlPrefix.indexOf("/") != 0) {
-+ urlPrefix = "/" + urlPrefix;
-+ }
-+ } else {
-+ urlPrefix = "";
-+ }
-+ System.out.println("urlPrefix: '" + urlPrefix + "'");
-+
-+ ftpDropDown = readParameter("ftpDropDown", false);
-+ if (ftpDropDown != null) {
-+ ftpDropDown = ftpDropDown.replaceAll("%2F", "/");
-+ ftpDropDown = ftpDropDown.replaceAll("%2f", "/");
-+ ftpDropDown = ftpDropDown.replaceAll("_2F_", "/");
-+ ftpDropDown = ftpDropDown.replaceAll("%20", " ");
-+ System.out.println("ftpDropDown: '" + ftpDropDown + "'");
-+ }
-+
-+
-+ oneTimeKey = readParameter("oneTimeKey", false);
-+ if (oneTimeKey != null) {
-+ System.out.println("oneTimeKey is set.");
-+ }
-+
-+ serverCert = readParameter("serverCert", false);
-+ if (serverCert != null) {
-+ System.out.println("serverCert is set.");
-+ }
-+
-+ forceProxy = false;
-+ proxyHost = null;
-+ proxyPort = null;
-+ str = readParameter("forceProxy", false);
-+ if (str != null) {
-+ if (str.equalsIgnoreCase("Yes")) {
-+ forceProxy = true;
-+ } else if (str.equalsIgnoreCase("No")) {
-+ forceProxy = false;
-+ } else {
-+ forceProxy = true;
-+ String[] pieces = str.split(" ");
-+ proxyHost = new String(pieces[0]);
-+ if (pieces.length >= 2) {
-+ proxyPort = new String(pieces[1]);
-+ } else {
-+ proxyPort = new String("8080");
-+ }
-+ }
-+ }
-+ str = readParameter("proxyHost", false);
-+ if (str != null) {
-+ proxyHost = new String(str);
-+ }
-+ str = readParameter("proxyPort", false);
-+ if (str != null) {
-+ proxyPort = new String(str);
-+ }
-+ if (proxyHost != null && proxyPort == null) {
-+ proxyPort = new String("8080");
-+ }
-+
-+ ignoreProxy = false;
-+ str = readParameter("ignoreProxy", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ ignoreProxy = true;
-+ }
-+
-+ trustAllVncCerts = false;
-+ str = readParameter("trustAllVncCerts", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ trustAllVncCerts = true;
-+ }
-+ trustUrlVncCert = false;
-+ str = readParameter("trustUrlVncCert", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ trustUrlVncCert = true;
-+ }
-+ debugCerts = false;
-+ str = readParameter("debugCerts", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ debugCerts = true;
-+ }
-+ debugKeyboard = false;
-+ str = readParameter("debugKeyboard", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ debugKeyboard = true;
-+ }
-+ mapF5_to_atsign = false;
-+ str = readParameter("mapF5_to_atsign", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ mapF5_to_atsign = true;
-+ }
-+ forbid_Ctrl_Alt = false;
-+ str = readParameter("forbid_Ctrl_Alt", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ forbid_Ctrl_Alt = true;
-+ }
-+ ignoreMSLogonCheck = false;
-+ str = readParameter("ignoreMSLogonCheck", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ ignoreMSLogonCheck = true;
-+ }
-+ ftpOnly = false;
-+ str = readParameter("ftpOnly", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ ftpOnly = true;
-+ }
-+ graftFtp = false;
-+ str = readParameter("graftFtp", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ graftFtp = true;
-+ }
-+ dsmActive = false;
-+ str = readParameter("dsmActive", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ dsmActive = true;
-+ }
-+ delayAuthPanel = false;
-+ str = readParameter("delayAuthPanel", false);
-+ if (str != null && str.equalsIgnoreCase("Yes")) {
-+ delayAuthPanel = true;
-+ }
-+// end runge/x11vnc
- }
-
- public String readParameter(String name, boolean required) {