SSL Java viewer work thru proxy. -sslGenCA, etc key/cert management utils for x11vnc. FBPM "support".

pull/1/head
runge 17 years ago
parent 1602b345f3
commit d14cf0a84c

@ -1,3 +1,8 @@
2006-04-05 Karl Runge <runge@karlrunge.com>
* classes/ssl: SSL Java viewer workarounds for firewall
proxies (signed applet as last resort, proxy.vnc).
include ssl_vncviewer stunnel wrapper script.
2006-03-28 Steven Carr <scarr@jsa-usa.com>
* SDLvncviewer.c, rfbproto.c, vncviewer.c, main.c, rfbserver.c,
rfb.h, rfbclient.h, rfbproto.h: add new encoding: KeyboardLedState

@ -1,2 +1,2 @@
EXTRA_DIST=VncViewer.jar index.vnc
EXTRA_DIST=VncViewer.jar index.vnc SignedVncViewer.jar proxy.vnc README ssl_vncviewer

@ -0,0 +1,72 @@
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:
ssl_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.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,70 @@
<!--
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
-->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=SignedVncViewer.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>

@ -0,0 +1,142 @@
#!/bin/sh
#
# ssl_vncviewer: wrapper for vncviewer to use stunnel SSL tunnel.
#
# You must have stunnel(8) installed on the system and in your
# PATH (n.b. stunnel is usually in an sbin subdir).
#
# You should have "x11vnc -ssl ..." or "x11vnc -stunnel ..."
# running as the VNC server.
#
# usage: ssl_vncviewer [cert-args] host:display <vncviewer-args>
#
# e.g.: ssl_vncviewer snoopy:0
# ssl_vncviewer snoopy:0 -encodings "copyrect tight zrle hextile"
#
# [cert-args] can be:
# -verify /path/to/cacert.pem
# -mycert /path/to/mycert.pem
#
# -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.
#
VNCVIEWERCMD="vncviewer"
PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH
help() {
head -26 $0 | tail +2
}
# grab our cmdline options:
while [ "X$1" != "X" ]
do
case $1 in
"-verify") shift; verify="$1"
;;
"-mycert") shift; mycert="$1"
;;
"-h"*) help; exit 0
;;
*) break
;;
esac
shift
done
orig="$1"
shift
# play around with host:display port:
if ! echo "$orig" | grep ':' > /dev/null; then
orig="$orig:0"
fi
host=`echo "$orig" | awk -F: '{print $1}'`
disp=`echo "$orig" | awk -F: '{print $2}'`
if [ $disp -lt 200 ]; then
port=`expr $disp + 5900`
fi
# try to find an open listening port via netstat(1):
use=""
if uname | grep Linux > /dev/null; then
inuse=`netstat -ant | grep LISTEN | awk '{print $4}' | sed 's/^.*://'`
try=5920
while [ $try -lt 6000 ]
do
if ! echo "$inuse" | grep -w $try > /dev/null; then
use=$try
break
fi
try=`expr $try + 1`
done
fi
if [ "X$use" = "X" ]; then
# otherwise choose a "random" one:
use=`date +%S`
use=`expr $use + 5920`
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$mycert" != "X" ]; then
cert="cert = $mycert"
fi
##debug = 7
tmp=/tmp/ssl_vncviewer.$$
cat > $tmp <<END
foreground = yes
pid =
client = yes
$verify
$cert
[vnc_stunnel]
accept = $use
connect= $host:$port
END
echo ""
echo "Using this stunnel configuration:"
cat $tmp
echo ""
sleep 1
echo "running: stunnel $tmp"
stunnel $tmp < /dev/tty > /dev/tty &
pid=$!
echo ""
# pause here to let the user supply a possible passphrase for the
# mycert key:
if [ "X$mycert" != "X" ]; then
sleep 4
fi
sleep 2
rm -f $tmp
if [ $use -ge 5900 ]; then
n=`expr $use - 5900`
fi
if echo "$0" | grep vncip > /dev/null; then
# hack for runge's special wrapper script vncip.
vncip "$@" localhost:$n
else
$VNCVIEWERCMD "$@" localhost:$n
fi
kill $pid

@ -38,7 +38,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/Makefile vnc_javasrc/Makefile
@$(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
+++ vnc_javasrc/RfbProto.java 2006-04-03 11:22:30.000000000 -0400
@@ -199,7 +199,21 @@
host = h;
port = p;
@ -64,8 +64,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/RfbProto.java vnc_javasrc/RfbProto
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 @@
+++ vnc_javasrc/SSLSocketToMe.java 2006-04-04 13:17:39.000000000 -0400
@@ -0,0 +1,1040 @@
+/*
+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
+ *
@ -92,7 +92,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+import java.io.*;
+import javax.net.ssl.*;
+import java.security.cert.*;
+import java.util.Vector;
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
@ -109,14 +109,32 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ 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;
+
+ Socket proxySock;
+ DataInputStream proxy_is;
+ OutputStream proxy_os;
+
+ /* trust contexts */
+ SSLContext trustloc_ctx;
+ SSLContext trustall_ctx;
+ SSLContext trusturl_ctx;
+ SSLContext trustone_ctx;
+
+ TrustManager[] trustAllCerts;
+ TrustManager[] trustUrlCert;
+ TrustManager[] trustOneCert;
+
+ boolean use_url_cert_for_auth = true;
+ boolean user_wants_to_see_cert = true;
+
+ /* cert(s) we retrieve from VNC server */
+ java.security.cert.Certificate[] serverCerts = null;
+ java.security.cert.Certificate[] trustallCerts = null;
+ java.security.cert.Certificate[] trusturlCerts = null;
+
+ SSLSocketToMe(String h, int p, VncViewer v) throws Exception {
+ host = h;
@ -131,6 +149,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+
+ /* create trust managers used if initial handshake fails: */
+
+
+ trustAllCerts = new TrustManager[] {
+ /*
+ * this one accepts everything.
@ -149,13 +168,65 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ 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.
+ */
+ 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 (trusturlCerts == null) {
+ throw new CertificateException(
+ "No Trust url Certs array.");
+ }
+ if (trusturlCerts.length < 1) {
+ throw new CertificateException(
+ "No Trust url Certs.");
+ }
+ if (trusturlCerts.length > 1) {
+ throw new CertificateException(
+ "Too many 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 > 1) {
+ throw new CertificateException(
+ "Too many this-certs.");
+ }
+ if (! trusturlCerts[0].equals(certs[0])) {
+ throw new CertificateException(
+ "Server Cert Changed != URL.");
+ }
+ dbg("URL: trusturlCerts[0] matches certs[0]");
+ }
+ }
+ };
+ trustOneCert = new TrustManager[] {
+ /*
+ * this one accepts only the retrieved server cert.
+ * this one accepts only the retrieved server cert
+ * by SSLSocket by this applet.
+ */
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[]
@ -170,19 +241,35 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) throws CertificateException {
+ if (serverCerts == null) {
+ 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 (trustallCerts.length > 1) {
+ throw new CertificateException(
+ "Too many Trust All Server Certs.");
+ }
+ if (certs == null) {
+ throw new CertificateException(
+ "No Server Certs array.");
+ "No this-certs array.");
+ }
+ if (serverCerts.length < 1) {
+ if (certs.length < 1) {
+ throw new CertificateException(
+ "No Server Certs.");
+ "No this-certs Certs.");
+ }
+ if (! serverCerts[0].equals(certs[0])) {
+ if (certs.length > 1) {
+ throw new CertificateException(
+ "Server Cert Changed.");
+ "Too many this-certs.");
+ }
+ dbg("serverCerts[0] matches certs[0]");
+ if (! trustallCerts[0].equals(certs[0])) {
+ throw new CertificateException(
+ "Server Cert Changed != TRUSTALL.");
+ }
+ dbg("ONE: trustallCerts[0] matches certs[0]");
+ }
+ }
+ };
@ -195,6 +282,18 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ * 2) to subsequently connect to the server if user agrees.
+ */
+
+ /* trust loc certs: */
+ try {
+ trustloc_ctx = SSLContext.getInstance("SSL");
+ trustloc_ctx.init(null, null, new
+ java.security.SecureRandom());
+
+ } catch (Exception e) {
+ String msg = "SSL trustloc_ctx FAILED.";
+ dbg(msg);
+ throw new Exception(msg);
+ }
+
+ /* trust all certs: */
+ try {
+ trustall_ctx = SSLContext.getInstance("SSL");
@ -207,6 +306,18 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new Exception(msg);
+ }
+
+ /* trust url certs: */
+ try {
+ trusturl_ctx = SSLContext.getInstance("SSL");
+ trusturl_ctx.init(null, trustUrlCert, new
+ java.security.SecureRandom());
+
+ } catch (Exception e) {
+ String msg = "SSL trusturl_ctx FAILED.";
+ dbg(msg);
+ throw new Exception(msg);
+ }
+
+ /* trust the one cert from server: */
+ try {
+ trustone_ctx = SSLContext.getInstance("SSL");
@ -220,23 +331,121 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ }
+ }
+
+ boolean browser_cert_match() {
+ String msg = "Browser URL accept previously accepted cert";
+
+ if (user_wants_to_see_cert) {
+ return false;
+ }
+
+ if (trustallCerts != null && trusturlCerts != null) {
+ if (trustallCerts.length == 1 && trusturlCerts.length == 1) {
+ if (trustallCerts[0].equals(trusturlCerts[0])) {
+ System.out.println(msg);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public Socket connectSock() throws IOException {
+
+ /* now connect to host:port */
+ socket = (SSLSocket) factory.createSocket(host, port);
+ /*
+ * first try a https connection to detect a proxy, and
+ * also grab the VNC server cert.
+ */
+ URL url = new URL("https://" + host + ":" + port +
+ "/check.https.proxy.connection");
+ try {
+ HttpsURLConnection https = (HttpsURLConnection)
+ url.openConnection();
+
+ https.setUseCaches(false);
+ https.setRequestMethod("GET");
+ https.setRequestProperty("Pragma", "No-Cache");
+ https.setRequestProperty("Proxy-Connection",
+ "Keep-Alive");
+ https.setDoInput(true);
+
+ https.connect();
+
+ trusturlCerts = https.getServerCertificates();
+
+ if (https.usingProxy()) {
+ proxy_in_use = true;
+ dbg("HTTPS proxy in use. There may be connection problems.");
+ }
+ Object output = https.getContent();
+ https.disconnect();
+
+ } catch(Exception e) {
+ trusturlCerts = null;
+ }
+
+ if (use_url_cert_for_auth && trusturlCerts != null) {
+ factory = trusturl_ctx.getSocketFactory();
+ } else {
+ factory = trustloc_ctx.getSocketFactory();
+ }
+
+ socket = null;
+ try {
+ socket = (SSLSocket) factory.createSocket(host, port);
+ } catch (Exception esock) {
+ if (proxy_in_use) {
+ proxy_failure = true;
+ dbg("HTTPS proxy in use. Trying to go with it.");
+ try {
+ socket = proxy_socket(factory);
+ } catch (Exception e) {
+ dbg("err proxy_socket: " + e.getMessage());
+ }
+ }
+ }
+
+ 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.");
+ dbg("Server Connection Verified on 1st try.");
+
+ java.security.cert.Certificate[] currentTrustedCerts;
+ BrowserCertsDialog bcd;
+
+ SSLSession sess = socket.getSession();
+ currentTrustedCerts = sess.getPeerCertificates();
+
+ if (currentTrustedCerts == null || currentTrustedCerts.length < 1) {
+ socket.close();
+ 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) {
+ ;
+ }
+
+ bcd = new BrowserCertsDialog(serv, host + ":" + port);
+ bcd.queryUser();
+ if (bcd.showCertDialog) {
+ String msg = "user wants to see cert";
+ dbg(msg);
+ user_wants_to_see_cert = true;
+ throw new SSLHandshakeException(msg);
+ } else {
+ user_wants_to_see_cert = false;
+ dbg("bcd: user said yes, accept it");
+ }
+
+ } catch (Exception ehand) {
+ } catch (SSLHandshakeException eh) {
+ dbg("Could not automatically verify Server.");
+ dbg("msg: " + eh.getMessage());
+
+ socket.close();
+ socket = null;
+
+ /*
+ * Reconnect, trusting any cert, so we can grab
@ -244,7 +453,11 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ * is not used for anything else.
+ */
+ factory = trustall_ctx.getSocketFactory();
+ socket = (SSLSocket) factory.createSocket(host, port);
+ if (proxy_failure) {
+ socket = proxy_socket(factory);
+ } else {
+ socket = (SSLSocket) factory.createSocket(host, port);
+ }
+
+ try {
+ socket.startHandshake();
@ -253,33 +466,32 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ /* grab the cert: */
+ try {
+ SSLSession sess = socket.getSession();
+ serverCerts = sess.getPeerCertificates();
+ trustallCerts = 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();
+ if (! browser_cert_match()) {
+ /*
+ * close socket now, we will reopen after
+ * dialog if user agrees to use the cert.
+ */
+ socket.close();
+ socket = null;
+
+ /* dialog with user to accept cert or not: */
+ /* dialog with user to accept cert or not: */
+
+ TrustDialog td= new TrustDialog(host, port,
+ serverCerts);
+ TrustDialog td= new TrustDialog(host, port,
+ trustallCerts);
+
+ if (! td.queryUser()) {
+ String msg = "User decided against it.";
+ dbg(msg);
+ throw new IOException(msg);
+ 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.");
+
@ -293,7 +505,11 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ */
+
+ factory = trustone_ctx.getSocketFactory();
+ socket = (SSLSocket) factory.createSocket(host, port);
+ if (proxy_failure) {
+ socket = proxy_socket(factory);
+ } else {
+ socket = (SSLSocket) factory.createSocket(host, port);
+ }
+
+ try {
+ socket.startHandshake();
@ -315,12 +531,171 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ System.out.println(s);
+ }
+ }
+
+ public SSLSocket proxy_socket(SSLSocketFactory factory) {
+ Properties props = null;
+ String proxyHost = null;
+ int proxyPort = 0;
+
+ /* see if we can guess the proxy info from Properties: */
+ try {
+ props = System.getProperties();
+ } catch (Exception e) {
+ dbg("props failed: " + e.getMessage());
+ }
+ if (props != null) {
+ dbg("\n---------------\nAll props:");
+ props.list(System.out);
+ dbg("\n---------------\n\n");
+
+ for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
+ String s = (String) e.nextElement();
+ String v = System.getProperty(s);
+ String l1 = s.toLowerCase();
+ String l2 = v.toLowerCase();
+
+ if (l1.indexOf("proxy") < 0 && l2.indexOf("proxy") < 0) {
+ continue;
+ }
+ if (l2.indexOf("https") < 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) {
+ 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) {
+ try {
+ Integer I = new Integer(hp[1]);
+ proxyPort = I.intValue();
+ } catch (Exception ex) {
+ continue;
+ }
+ proxyHost = new String(hp[0]);
+ break;
+ }
+ }
+ }
+ }
+ 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();
+ dbg("User said host: " + pd.getHost() + " port: " + pd.getPort());
+ }
+
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("1 sadly, returning a null socket");
+ return null;
+ }
+ String hp = host + ":" + port;
+
+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n\r\n";
+
+ /* not working for SSL yet: */
+ String req2 = "GET https://" + hp
+ + "/request.https.proxy.connection HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n\r\n";
+
+ dbg("requesting: " + req1);
+
+ try {
+ proxy_os.write(req1.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied: " + reply);
+
+ if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2 sadly, returning a null socket");
+ return null;
+ }
+ dbg("requesting: " + req2);
+ proxy_os.write(req2.getBytes());
+
+ reply = readline(proxy_is);
+
+ dbg("proxy replied: " + reply);
+ }
+ } catch(Exception e) {
+ dbg("sock prob: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line: " + line);
+ 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[] serverCerts = null;
+ java.security.cert.Certificate[] trustallCerts = null;
+ boolean viewing_cert = false;
+ boolean trust_this_session = false;
+
@ -339,51 +714,34 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ + " this VNC server";
+ String ln = "\n---------------------------------------------------\n\n";
+
+ TrustDialog (String h, int p, java.security.cert.Certificate[] certs) {
+ TrustDialog (String h, int p, java.security.cert.Certificate[] s) {
+ host = h;
+ port = p;
+ serverCerts = certs;
+ trustallCerts = s;
+
+ 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);
+
+ String infostr = "";
+ if (trustallCerts.length == 1) {
+ CertInfo ci = new CertInfo(trustallCerts[0]);
+ infostr = ci.get_certinfo("all");
+ }
+
+ text = "\n"
++ "Unable to verify the identity of\n"
++ "\n"
++ " " + host + ":" + port + "\n"
++ "\n"
++ get_certinfo()
++ infostr
++ "\n"
++ "as a trusted VNC server.\n"
++ "\n"
@ -473,12 +831,12 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ int i;
+ /* show all (likely just one) certs: */
+ textarea.setText("");
+ for (i=0; i < serverCerts.length; i++) {
+ for (i=0; i < trustallCerts.length; i++) {
+ int j = i + 1;
+ textarea.append("Certificate[" +
+ j + "]\n\n");
+ textarea.append(
+ serverCerts[i].toString());
+ trustallCerts[i].toString());
+ textarea.append(ln);
+ }
+ viewcert.setLabel("View Info");
@ -508,11 +866,11 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ String all = "";
+ String fields[] = {"CN", "OU", "O", "L", "C"};
+ int i;
+ if (serverCerts.length < 1) {
+ if (trustallCerts.length < 1) {
+ all = "";
+ return all;
+ }
+ String cert = serverCerts[0].toString();
+ String cert = trustallCerts[0].toString();
+
+ /*
+ * For now we simply scrape the cert string, there must
@ -547,6 +905,207 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ 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();
+ }
+ }
+}
+
+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 = "\nShould this VNC Viewer applet use your Browser/JVM certs to\n";
+ m += "authenticate the VNC Server:\n";
+ m += "\n " + hostport + "\n\n " + vncServer + "\n\n";
+ m += "(NOTE: this *includes* any certs you have Just Now accepted in a\n";
+ m += "dialog box with your Web Browser or Java Applet Plugin)\n\n";
+
+ TextArea textarea = new TextArea(m, 12, 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. */
+ return;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == yes) {
+ showCertDialog = false;
+ dialog.dispose();
+ } else if (evt.getSource() == no) {
+ showCertDialog = true;
+ dialog.dispose();
+ }
+ }
+}
+
+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 "";
+ }
+ }
+}
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

@ -59,6 +59,7 @@ AH_TEMPLATE(HAVE_LIBXTRAP, [DEC-XTRAP extension build environment present])
AH_TEMPLATE(HAVE_RECORD, [RECORD extension build environment present])
AH_TEMPLATE(HAVE_SOLARIS_XREADSCREEN, [Solaris XReadScreen available])
AH_TEMPLATE(HAVE_IRIX_XREADDISPLAY, [IRIX XReadDisplay available])
AH_TEMPLATE(HAVE_FBPM, [FBPM extension build environment present])
AC_ARG_WITH(xkeyboard,
[ --without-xkeyboard disable xkeyboard extension support],,)
@ -74,6 +75,8 @@ AC_ARG_WITH(xtrap,
[ --without-xtrap disable xtrap extension support],,)
AC_ARG_WITH(xrecord,
[ --without-xrecord disable xrecord extension support],,)
AC_ARG_WITH(fbpm,
[ --without-fbpm disable fbpm extension support],,)
if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
AC_CHECK_LIB(X11, XGetImage, HAVE_X="true",
@ -95,6 +98,11 @@ if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
[AC_DEFINE(HAVE_IRIX_XREADDISPLAY)], ,
[#include <X11/Xlib.h>])
AC_CHECK_HEADER(X11/extensions/fbpm.h,
[AC_DEFINE(HAVE_FBPM)], ,
[#include <X11/Xlib.h>
#include <X11/Xmd.h>])
AC_CHECK_LIB(Xtst, XTestGrabControl,
X_PRELIBS="-lXtst $X_PRELIBS"
[AC_DEFINE(HAVE_XTESTGRABCONTROL) HAVE_XTESTGRABCONTROL="true"], ,

@ -62,7 +62,7 @@ cp classes/ssl/Makefile.am classes/ssl/Makefile.am.LibVNCServer
sed -e 's/EXTRA_DIST=/EXTRA_DIST=tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab-traversal.patch /' \
classes/ssl/Makefile.am.LibVNCServer > classes/ssl/Makefile.am
echo 'pkgdatadir = $(datadir)/@PACKAGE@/classes/ssl' >> classes/ssl/Makefile.am
echo 'pkgdata_DATA=VncViewer.jar index.vnc' >> classes/ssl/Makefile.am
echo 'pkgdata_DATA=VncViewer.jar index.vnc SignedVncViewer.jar proxy.vnc ssl_vncviewer README' >> classes/ssl/Makefile.am
mv acinclude.m4 acinclude.m4.LibVNCServer

@ -1,3 +1,10 @@
2006-04-05 Karl Runge <runge@karlrunge.com>
* x11vnc: add FBPM support (-fbpm) for Suns. -rawfb ZERO for
testing. Basic key+cert management utilities: -sslGenCA,
-sslGenCert, -sslEncKey, -sslDelCert, -sslCertInfo, and
addln features. SSL proxy connection. -storepasswd with
no args or pw echo.
2006-03-26 Karl Runge <runge@karlrunge.com>
* x11vnc: -xinerama now on by default. In -ssl mode accept https
applet downloads thru VNC port. -https option for 2nd https

@ -13,7 +13,7 @@ endif
if HAVE_X
bin_PROGRAMS=x11vnc
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c options.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c unixpw.c user.c userinput.c util.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h options.h params.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h tkx11vnc.h unixpw.h user.h userinput.h util.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c unixpw.c user.c userinput.c util.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h unixpw.h user.h userinput.h util.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
INCLUDES=@X_CFLAGS@
x11vnc_LDADD=$(LDADD) @X_LIBS@ $(LD_CYGIPC)
endif

File diff suppressed because it is too large Load Diff

@ -33,6 +33,7 @@ int trap_getimage_xerror(Display *d, XErrorEvent *error);
char *xerror_string(XErrorEvent *error);
void initialize_crash_handler(void);
void initialize_signals(void);
void unset_signals(void);
int known_sigpipe_mode(char *s);
@ -107,8 +108,13 @@ static void clean_icon_mode(void) {
* Normal exiting
*/
void clean_up_exit (int ret) {
static int depth = 0;
exit_flag = 1;
if (depth++ > 2) {
exit(ret);
}
if (icon_mode) {
clean_icon_mode();
}
@ -427,6 +433,19 @@ void initialize_signals(void) {
X_UNLOCK;
}
void unset_signals(void) {
signal(SIGHUP, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGABRT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
}
int known_sigpipe_mode(char *s) {
/*
* skip, ignore, exit

@ -20,6 +20,7 @@ extern int trap_getimage_xerror(Display *d, XErrorEvent *error);
extern char *xerror_string(XErrorEvent *error);
extern void initialize_crash_handler(void);
extern void initialize_signals(void);
extern void unset_signals(void);
extern int known_sigpipe_mode(char *s);
#endif /* _X11VNC_CLEANUP_H */

@ -2190,4 +2190,3 @@ void check_new_clients(void) {
}
}

@ -528,14 +528,14 @@ void print_help(int mode) {
"-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n"
" use the traditional getpwnam(3) + crypt(3) method to\n"
" verify passwords instead. This requires that the\n"
" encrpyted passwords be readable. Passwords stored\n"
" encrypted passwords be readable. Passwords stored\n"
" in /etc/shadow will be inaccessible unless x11vnc\n"
" is run as root.\n"
"\n"
" This is called \"NIS\" mode simply because in most\n"
" NIS setups the user encrypted passwords are accessible\n"
" (e.g. \"ypcat passwd\"). NIS is not required for this\n"
" mode to work (only that getpwnam(3) return the encrpyted\n"
" mode to work (only that getpwnam(3) return the encrypted\n"
" password is required), but it is unlikely it will work\n"
" for any other modern environment. All of the -unixpw\n"
" options and contraints apply.\n"
@ -549,18 +549,19 @@ void print_help(int mode) {
"\n"
" [pem] is optional, use \"-ssl /path/to/mycert.pem\"\n"
" to specify a PEM certificate file to use to identify\n"
" and provide a key for this server. See openssl(1)\n"
" for what a PEM can be.\n"
" and provide a key for this server. See openssl(1) for\n"
" more info about PEMs and the -sslGenCert option below.\n"
"\n"
" Connecting VNC viewer SSL tunnels can optionally\n"
" The connecting VNC viewer SSL tunnel can optionally\n"
" authenticate this server if they have the public\n"
" key part of the certificate (or a common certificate\n"
" authority, CA, is a more sophisicated way to verify\n"
" this server's cert). This is used to prevent\n"
" man-in-the-middle attacks. Otherwise, if the VNC\n"
" viewer accepts this server's key without verification,\n"
" at least the traffic is protected from passive sniffing\n"
" on the network (but NOT from man-in-the-middle attacks).\n"
" this server's cert, see -sslGenCA below). This is\n"
" used to prevent man-in-the-middle attacks. Otherwise,\n"
" if the VNC viewer accepts this server's key without\n"
" verification, at least the traffic is protected\n"
" from passive sniffing on the network (but NOT from\n"
" man-in-the-middle attacks).\n"
"\n"
" If [pem] is not supplied and the openssl(1) utility\n"
" command exists in PATH, then a temporary, self-signed\n"
@ -573,15 +574,34 @@ void print_help(int mode) {
" temporary certificate, the public part of it will be\n"
" displayed to stderr (e.g. one could copy it to the\n"
" client-side to provide authentication of the server to\n"
" VNC viewers.)\n"
" VNC viewers.) See following paragraphs for how to save\n"
" keys to reuse when x11vnc is restarted.\n"
"\n"
" Set the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc\n"
" print out the entire certificate, including the PRIVATE\n"
" KEY part, to stderr. One could reuse this cert if saved\n"
" in a [pem] file. Similarly, set X11VNC_KEEP_TMP_PEM=1\n"
" to not delete the temporary PEM file: the file name\n"
" will be printed to stderr (so one could move it to a\n"
" safe place for reuse).\n"
" will be printed to stderr (so one could move it to\n"
" a safe place for reuse). You will be prompted for a\n"
" passphrase for the private key.\n"
"\n"
" If [pem] is \"SAVE\" then the certificate will be saved\n"
" to the file ~/.vnc/certs/server.pem, or if that file\n"
" exists it will be used directly. Similarly, if [pem]\n"
" is \"SAVE_PROMPT\" the server.pem certificate will be\n"
" made based on your answers to its prompts for info such\n"
" as OrganizationalName, CommonName, etc.\n"
"\n"
" Use \"SAVE-<string>\" and \"SAVE_PROMPT-<string>\"\n"
" to refer to the file ~/.vnc/certs/server-<string>.pem\n"
" instead. E.g. \"SAVE-charlie\" will store to the file\n"
" ~/.vnc/certs/server-charlie.pem\n"
"\n"
" See -ssldir below to use a directory besides the\n"
" default ~/.vnc/certs\n"
"\n"
" Example: x11vnc -ssl SAVE -display :0 ...\n"
"\n"
" Reverse connections are disabled in -ssl mode because\n"
" there is no way to ensure that data channel will\n"
@ -589,33 +609,369 @@ void print_help(int mode) {
" override this.\n"
"\n"
" Your VNC viewer will also need to be able to connect\n"
" via SSL. See the discussion below under -stunnel\n"
" and the FAQ for how this might be achieved. E.g. on\n"
" Unix it is easy to write a shell script that starts up\n"
" stunnel and then vncviewer. Also in the x11vnc source\n"
" a SSL enabled Java VNC Viewer applet is provided in\n"
" the classes/ssl directory.\n"
" via SSL. See the discussion below under -stunnel and\n"
" the FAQ (ssl_vncviewer script) for how this might be\n"
" achieved. E.g. on Unix it is easy to write a shell\n"
" script that starts up stunnel and then vncviewer.\n"
" Also in the x11vnc source a SSL enabled Java VNC Viewer\n"
" applet is provided in the classes/ssl directory.\n"
"\n"
"-ssldir [dir] Use [dir] as an alternate ssl certificate and key\n"
" management toplevel directory. The default is\n"
" ~/.vnc/certs\n"
"\n"
" This directory is used to store server and other\n"
" certificates and keys and also other materials. E.g. in\n"
" the simplest case, \"-ssl SAVE\" will store the x11vnc\n"
" server cert in [dir]/server.pem\n"
"\n"
" Use of alternate directories via -ssldir allows you to\n"
" manage multiple VNC Certificate Authority (CA) keys.\n"
" Another use is if ~/.vnc/cert is on an NFS share you\n"
" might want your certificates and keys to be on a local\n"
" filesystem to prevent network snooping (for example\n"
" -ssldir /var/lib/x11vnc-certs).\n"
"\n"
" -ssldir effects the other -ssl* options. In the case\n"
" of maintenance commands where the VNC server is not run\n"
" (e.g. -sslGenCA), the -ssldir option must precede the\n"
" command. E.g. x11vnc -ssldir ~/mydir -sslCertInfo LIST\n"
"\n"
"-sslverify [path] For either of the -ssl or -stunnel modes, use [path]\n"
" to provide certificates to authenticate incoming VNC\n"
" client connections. This can be used as a method to\n"
" replace standard password authentication of clients.\n"
" *Client* connections (normally only the server is\n"
" authenticated in SSL.) This can be used as a method\n"
" to replace standard password authentication of clients.\n"
"\n"
" If [path] is a directory it contains the client (or CA)\n"
" certificates in separate files. If [path] is a file, it\n"
" contains multiple certificates. These correspond to the\n"
" \"CApath = dir\" and \"CAfile = file\" stunnel options.\n"
" See the stunnel(8) manpage for details.\n"
" certificates in separate files. If [path] is a file,\n"
" it contains multiple certificates. See special tokens\n"
" below. These correspond to the \"CApath = dir\" and\n"
" \"CAfile = file\" stunnel options. See the stunnel(8)\n"
" manpage for details.\n"
"\n"
" Examples:\n"
" x11vnc -ssl -sslverify ~/my.pem\n"
" x11vnc -ssl -sslverify ~/my_pem_dir/\n"
"\n"
" Note that if [path] is a directory, it must contain\n"
" the certs in separate files named like <HASH>.0, where\n"
" the value of <HASH> is found by running the command\n"
" \"openssl x509 -hash -noout -in file.crt\". Evidently\n"
" one uses <HASH>.1 if there is a collision...\n"
"\n"
" The the key-management utility \"-sslCertInfo HASHON\"\n"
" and \"-sslCertInfo HASHOFF\" will create/delete these\n"
" hashes for you automatically (via symlink) in the HASH\n"
" subdirs it manages. Then you can point -sslverify to\n"
" the HASH subdir.\n"
"\n"
" Special tokens: in -ssl mode, if [path] is not a file or\n"
" a directory, it is taken as a comma separated list of\n"
" tokens that are interpreted as follows:\n"
"\n"
" If a token is \"CA\" that means load the CA/cacert.pem\n"
" file from the ssl directory. If a token is \"clients\"\n"
" then all the files clients/*.crt in the ssl directory\n"
" are loaded. Otherwise the file clients/token.crt\n"
" is attempted to be loaded. As a kludge, use a token\n"
" like ../server-foo to load a server cert if you find\n"
" that necessary.\n"
" \n"
" Use -ssldir to use a directory different from the\n"
" ~/.vnc/certs default.\n"
" \n"
" Note that if the \"CA\" cert is loaded you do not need\n"
" to load any of the certs that have been signed by it.\n"
" You will need to load any additional self-signed certs\n"
" however.\n"
" \n"
" Examples:\n"
" x11vnc -ssl -sslverify CA\n"
" x11vnc -ssl -sslverify self:fred,self:jim\n"
" x11vnc -ssl -sslverify CA,clients\n"
" \n"
" Usually \"-sslverify CA\" is the most effective.\n"
" See the -sslGenCA and -sslGenCert options below for\n"
" how to set up and manage the CA framework.\n"
" \n"
"\n"
"\n"
" NOTE: the following utilities, -sslGenCA, -sslGenCert,\n"
" -sslEncKey, and -sslCertInfo are provided for\n"
" completeness, but for casual usage they are overkill.\n"
"\n"
" They provide VNC Certificate Authority (CA) key creation\n"
" and server / client key generation and signing. So they\n"
" provide a basic Public Key management framework for\n"
" VNC-ing with x11vnc. (note that they require openssl(1)\n"
" be installed on the system)\n"
"\n"
" However, the simplest usage mode (where x11vnc\n"
" automatically generates its own, self-signed, temporary\n"
" key and the VNC viewers always accept it, e.g. accepting\n"
" via a dialog box) is probably safe enough for most\n"
" scenarios. CA management is not needed.\n"
"\n"
" To protect against Man-In-The-Middle attacks the\n"
" simplest mode can be improved by using \"-ssl SAVE\"\n"
" to have x11vnc create a longer term self-signed\n"
" certificate, and then (safely) copy the corresponding\n"
" public key cert to the desired client machines (care\n"
" must be taken the private key part is not stolen;\n"
" you will be prompted for a passphrase).\n"
"\n"
" So keep in mind no CA key creation or management\n"
" (-sslGenCA and -sslGenCert) is needed for either of\n"
" the above two common usage modes.\n"
"\n"
" One might want to use -sslGenCA and -sslGenCert\n"
" if you had a large number of VNC client and server\n"
" workstations. That way the administrator could generate\n"
" a single CA key with -sslGenCA and distribute its\n"
" certificate part to all of the workstations.\n"
"\n"
" Next, he could create signed VNC server keys\n"
" (-sslGenCert server ...) for each workstation or user\n"
" that then x11vnc would use to authenticate itself to\n"
" any VNC client that has the CA cert.\n"
"\n"
" Optionally, the admin could also make it so the\n"
" VNC clients themselves are authenticated to x11vnc\n"
" (-sslGenCert client ...) For this -sslverify would be\n"
" pointed to the CA cert (and/or self-signed certs).\n"
"\n"
" x11vnc will be able to use all of these cert and\n"
" key files. On the VNC client side, they will need to\n"
" be \"imported\" somehow. Web browsers have \"Manage\n"
" Certificates\" actions as does the Java applet plugin\n"
" Control Panel. stunnel can also use these files (see\n"
" the ssl_vncviewer example script in the FAQ.)\n"
"\n"
"-sslGenCA [dir] Generate your own Certificate Authority private key,\n"
" certificate, and other files in directory [dir].\n"
"\n"
" If [dir] is not supplied, a -ssldir setting is used,\n"
" or otherwise ~/.vnc/certs is used.\n"
"\n"
" This command also creates directories where server and\n"
" client certs and keys will be stored. The openssl(1)\n"
" program must be installed on the system and available\n"
" in PATH.\n"