diff options
author | runge <runge> | 2006-03-28 05:43:04 +0000 |
---|---|---|
committer | runge <runge> | 2006-03-28 05:43:04 +0000 |
commit | 5920dc18d75a53690ed8690867f501c51595daf1 (patch) | |
tree | 4f2eb03ac80b27ba03dedaa1a4b32640703b3d02 /classes | |
parent | 10c61b53c275f125432fa20d8348aafcfed2bf93 (diff) | |
download | libtdevnc-5920dc18d75a53690ed8690867f501c51595daf1.tar.gz libtdevnc-5920dc18d75a53690ed8690867f501c51595daf1.zip |
SSL patch for Java viewer. https support for x11vnc.
Diffstat (limited to 'classes')
-rw-r--r-- | classes/Makefile.am | 3 | ||||
-rw-r--r-- | classes/ssl/Makefile.am | 2 | ||||
-rw-r--r-- | classes/ssl/VncViewer.jar | bin | 0 -> 61835 bytes | |||
-rw-r--r-- | classes/ssl/index.vnc | 26 | ||||
-rw-r--r-- | classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch | 57 | ||||
-rw-r--r-- | classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch | 573 |
6 files changed, 661 insertions, 0 deletions
diff --git a/classes/Makefile.am b/classes/Makefile.am index 7b74396..c5497a8 100644 --- a/classes/Makefile.am +++ b/classes/Makefile.am @@ -1,2 +1,5 @@ EXTRA_DIST=VncViewer.jar index.vnc javaviewer.pseudo_proxy.patch +SUBDIRS = ssl +DIST_SUBDIRS = ssl + diff --git a/classes/ssl/Makefile.am b/classes/ssl/Makefile.am new file mode 100644 index 0000000..66c8719 --- /dev/null +++ b/classes/ssl/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=VncViewer.jar index.vnc + diff --git a/classes/ssl/VncViewer.jar b/classes/ssl/VncViewer.jar Binary files differnew file mode 100644 index 0000000..7e36267 --- /dev/null +++ b/classes/ssl/VncViewer.jar diff --git a/classes/ssl/index.vnc b/classes/ssl/index.vnc new file mode 100644 index 0000000..292b06c --- /dev/null +++ b/classes/ssl/index.vnc @@ -0,0 +1,26 @@ +<!-- + 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.tightvnc.com/">TightVNC site</A> +</HTML> 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 new file mode 100644 index 0000000..db611af --- /dev/null +++ b/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch @@ -0,0 +1,57 @@ +--- vnc_javasrc.orig/VncCanvas.java 2004-10-10 02:15:54.000000000 -0400 ++++ vnc_javasrc/VncCanvas.java 2006-03-27 22:34:02.000000000 -0500 +@@ -28,6 +28,7 @@ + import java.lang.*; + import java.util.zip.*; + ++import java.util.Collections; + + // + // VncCanvas is a subclass of Canvas which draws a VNC desktop on it. +@@ -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)); +@@ -1387,9 +1402,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 +1418,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 new file mode 100644 index 0000000..48f0dc4 --- /dev/null +++ b/classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch @@ -0,0 +1,573 @@ +diff -x VncCanvas.java -Naur vnc_javasrc.orig/Makefile vnc_javasrc/Makefile +--- vnc_javasrc.orig/Makefile 2004-03-04 08:34:25.000000000 -0500 ++++ vnc_javasrc/Makefile 2006-03-26 17:29:25.000000000 -0500 +@@ -15,25 +15,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) -target 1.4 -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 -x VncCanvas.java -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 2006-03-27 22:26:25.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 { +diff -x VncCanvas.java -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 2006-03-27 20:45:59.000000000 -0500 +@@ -0,0 +1,481 @@ ++/* ++ * 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. ++ * ++ * 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.security.cert.*; ++import java.util.Vector; ++ ++import java.awt.*; ++import java.awt.event.*; ++ ++public class SSLSocketToMe { ++ ++ /* basic member data: */ ++ String host; ++ int port; ++ VncViewer viewer; ++ boolean debug = true; ++ ++ /* sockets */ ++ SSLSocket socket = null; ++ SSLSocketFactory factory; ++ ++ /* trust contexts */ ++ SSLContext trustall_ctx; ++ SSLContext trustone_ctx; ++ TrustManager[] trustAllCerts; ++ TrustManager[] trustOneCert; ++ ++ /* cert(s) we retrieve from VNC server */ ++ java.security.cert.Certificate[] serverCerts = null; ++ ++ SSLSocketToMe(String h, int p, VncViewer v) throws Exception { ++ host = h; ++ port = p; ++ viewer = v; ++ ++ /* we will first try default factory for certification: */ ++ ++ factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); ++ ++ dbg("SSL startup: " + host + " " + port); ++ ++ /* create trust managers used if initial handshake fails: */ ++ ++ trustAllCerts = new TrustManager[] { ++ /* ++ * this one accepts everything. ++ */ ++ 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 */ ++ } ++ } ++ }; ++ ++ trustOneCert = new TrustManager[] { ++ /* ++ * this one accepts only the retrieved server cert. ++ */ ++ 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"); ++ } ++ public void checkServerTrusted( ++ java.security.cert.X509Certificate[] certs, ++ String authType) throws CertificateException { ++ if (serverCerts == null) { ++ throw new CertificateException( ++ "No Server Certs array."); ++ } ++ if (serverCerts.length < 1) { ++ throw new CertificateException( ++ "No Server Certs."); ++ } ++ if (! serverCerts[0].equals(certs[0])) { ++ throw new CertificateException( ++ "Server Cert Changed."); ++ } ++ dbg("serverCerts[0] matches certs[0]"); ++ } ++ } ++ }; ++ ++ /* ++ * They are used: ++ * ++ * 1) to retrieve the server cert in case of failure to ++ * display it to the user. ++ * 2) to subsequently connect to the server if user agrees. ++ */ ++ ++ /* trust all certs: */ ++ try { ++ trustall_ctx = SSLContext.getInstance("SSL"); ++ trustall_ctx.init(null, trustAllCerts, new ++ java.security.SecureRandom()); ++ ++ } catch (Exception e) { ++ String msg = "SSL trustall_ctx FAILED."; ++ dbg(msg); ++ throw new Exception(msg); ++ } ++ ++ /* trust the one cert from server: */ ++ try { ++ trustone_ctx = SSLContext.getInstance("SSL"); ++ trustone_ctx.init(null, trustOneCert, new ++ java.security.SecureRandom()); ++ ++ } catch (Exception e) { ++ String msg = "SSL trustone_ctx FAILED."; ++ dbg(msg); ++ throw new Exception(msg); ++ } ++ } ++ ++ public Socket connectSock() throws IOException { ++ ++ /* now connect to host:port */ ++ socket = (SSLSocket) factory.createSocket(host, port); ++ ++ try { ++ /* ++ * Verified the first time! How can that be? ;-) ++ * They actually went thru the trouble to set it up? ++ */ ++ socket.startHandshake(); ++ dbg("Server Connection Verified."); ++ ++ } catch (Exception ehand) { ++ dbg("Could not automatically verify Server."); ++ ++ socket.close(); ++ ++ /* ++ * Reconnect, trusting any cert, so we can grab ++ * the cert to show it to the user. The connection ++ * is not used for anything else. ++ */ ++ factory = trustall_ctx.getSocketFactory(); ++ socket = (SSLSocket) factory.createSocket(host, port); ++ ++ try { ++ socket.startHandshake(); ++ dbg("TrustAll Server Connection Verified."); ++ ++ /* grab the cert: */ ++ try { ++ SSLSession sess = socket.getSession(); ++ serverCerts = sess.getPeerCertificates(); ++ } catch (Exception e) { ++ throw new Exception("Could not get " + ++ "Peer Certificate"); ++ } ++ ++ /* ++ * close socket now, we will reopen after ++ * dialog if user agrees to use the cert. ++ */ ++ socket.close(); ++ ++ /* dialog with user to accept cert or not: */ ++ ++ TrustDialog td= new TrustDialog(host, port, ++ serverCerts); ++ ++ if (! td.queryUser()) { ++ String msg = "User decided against it."; ++ dbg(msg); ++ throw new IOException(msg); ++ } ++ ++ // idea to save certs for reconnections. ++ // not working (RfbProto thread terminates). ++ //viewer.acceptedCerts.addCerts(serverCerts); ++ ++ } catch (Exception ehand2) { ++ dbg("** Could not TrustAll Verify Server."); ++ ++ throw new IOException(ehand2.getMessage()); ++ } ++ ++ /* ++ * Now connect a 3rd time, using the cert ++ * retrieved during connection 2 (that the user ++ * likely blindly agreed to). ++ */ ++ ++ factory = trustone_ctx.getSocketFactory(); ++ socket = (SSLSocket) factory.createSocket(host, port); ++ ++ try { ++ socket.startHandshake(); ++ dbg("TrustAll Server Connection Verified #3."); ++ ++ } catch (Exception ehand3) { ++ dbg("** Could not TrustAll Verify Server #3."); ++ ++ throw new IOException(ehand3.getMessage()); ++ } ++ } ++ ++ dbg("SSL returning socket to caller."); ++ return (Socket) socket; ++ } ++ ++ private void dbg(String s) { ++ if (debug) { ++ System.out.println(s); ++ } ++ } ++} ++ ++class TrustDialog implements ActionListener { ++ String msg, host, text; ++ int port; ++ java.security.cert.Certificate[] serverCerts = 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[] certs) { ++ host = h; ++ port = p; ++ serverCerts = certs; ++ ++ msg = "VNC Server " + host + ":" + port + " Not Verified"; ++ } ++ ++ public boolean queryUser() { ++ ++// idea to save certs between connections. not working, everything is ++// cleared after each new connection. ++// ++// public boolean queryUser(VncViewer viewer) { ++// int i, j; ++// java.security.cert.Certificate cert; ++// ++// for (i=0; i < viewer.acceptedCerts.allCerts.size(); i++) { ++// System.out.println("try " + i); ++// ++// cert = (java.security.cert.Certificate) ++// viewer.acceptedCerts.allCerts.elementAt(i); ++// ++// for (j=0; j < serverCerts.length; j++) { ++// System.out.println("try " + i + " " + j); ++// if (serverCerts[j].equals(cert)) { ++// System.out.println("accept previously accepted cert"); ++// /* matched, no need for dialog */ ++// return true; ++// } ++// } ++// } ++ ++ /* create and display the dialog for unverified cert. */ ++ ++ Frame frame = new Frame(msg); ++ ++ dialog = new Dialog(frame, true); ++ ++ text = "\n" +++ "Unable to verify the identity of\n" +++ "\n" +++ " " + host + ":" + port + "\n" +++ "\n" +++ get_certinfo() +++ "\n" +++ "as a trusted VNC server.\n" +++ "\n" +++ "This may be due to:\n" +++ "\n" +++ " - The VNC server using a Self-Signed Certificate.\n" +++ "\n" +++ " - The VNC server using a Certificate Authority not recognized by your\n" +++ " Java applet runtime.\n" +++ "\n" +++ " - A Man-In-The-Middle attack impersonating as the VNC server you wish\n" +++ " to connect to.\n" +++ "\n" +++ "By copying the VNC server's Certificate (or using a common Certificate\n" +++ "Authority certificate) you can configure your Java applet runtime to\n" +++ "automatically authenticate the Server.\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, 28, 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 < serverCerts.length; i++) { ++ int j = i + 1; ++ textarea.append("Certificate[" + ++ j + "]\n\n"); ++ textarea.append( ++ serverCerts[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(); ++ ++ } else if (evt.getSource() == cancel) { ++ /* Cancel button clicked */ ++ trust_this_session = false; ++ ++ dialog.dispose(); ++ } ++ } ++ ++ String get_certinfo() { ++ String all = ""; ++ String fields[] = {"CN", "OU", "O", "L", "C"}; ++ int i; ++ if (serverCerts.length < 1) { ++ all = ""; ++ return all; ++ } ++ String cert = serverCerts[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; ++ } ++} +diff -x VncCanvas.java -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 2006-03-27 22:20:19.000000000 -0500 +@@ -87,6 +87,7 @@ + int deferScreenUpdates; + int deferCursorUpdates; + int deferUpdateRequests; ++ boolean disableSSL; + + // Reference to this applet for inter-applet communication. + public static java.applet.Applet refApplet; +@@ -626,6 +627,12 @@ + + // SocketFactory. + socketFactory = readParameter("SocketFactory", false); ++ ++ // SSL ++ disableSSL = false; ++ str = readParameter("DisableSSL", false); ++ if (str != null && str.equalsIgnoreCase("Yes")) ++ disableSSL = true; + } + + public String readParameter(String name, boolean required) { |