Shared TDE VNC library sources
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libtdevnc/webclients/java-applet/ssl/tightvnc-1.3dev7_javasrc-vn...

2601 lines
75 KiB

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);