SSL patch for Java viewer. https support for x11vnc.

pull/1/head
runge 18 years ago
parent 10c61b53c2
commit 5920dc18d7

@ -1,3 +1,8 @@
2006-03-28 Karl Runge <runge@karlrunge.com>
* classes/ssl: patch to tightvnc Java viewer for SSL support
plus other fixes (richcursor colors, Tab keysym, etc).
* libvncserver/httpd.c: add missing \r in 200 OK.
2006-03-27 Steven Carr <scarr@jsa-usa.com> 2006-03-27 Steven Carr <scarr@jsa-usa.com>
* rfbserver.c: Zlib encoding cannot have a limit via * rfbserver.c: Zlib encoding cannot have a limit via
maxRectsPerUpdate maxRectsPerUpdate

@ -1,2 +1,5 @@
EXTRA_DIST=VncViewer.jar index.vnc javaviewer.pseudo_proxy.patch EXTRA_DIST=VncViewer.jar index.vnc javaviewer.pseudo_proxy.patch
SUBDIRS = ssl
DIST_SUBDIRS = ssl

@ -0,0 +1,2 @@
EXTRA_DIST=VncViewer.jar index.vnc

Binary file not shown.

@ -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>

@ -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

@ -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) {

@ -184,30 +184,36 @@ if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
if test -z "$HAVE_LIBC_CRYPT"; then if test -z "$HAVE_LIBC_CRYPT"; then
AC_CHECK_LIB(crypt, crypt, AC_CHECK_LIB(crypt, crypt,
X_PRELIBS="$X_PRELIBS -lcrypt" X_PRELIBS="$X_PRELIBS -lcrypt"
[AC_DEFINE(HAVE_LIBCRYPT)], , [AC_DEFINE(HAVE_LIBCRYPT)], ,)
$X_LIBS $X_PRELIBS -lcrypt $X_EXTRA_LIBS)
fi fi
fi fi
AH_TEMPLATE(HAVE_LIBSSL, [openssl libssl library present])
AC_ARG_WITH(ssl, # some OS's need both -lssl and -lcrypto on link line:
[ --without-ssl disable support for openssl libssl],,)
if test "x$with_ssl" != "xno"; then
AC_CHECK_LIB(ssl, SSL_library_init,
X_PRELIBS="$X_PRELIBS -lssl"
[AC_DEFINE(HAVE_LIBSSL) HAVE_LIBSSL="true"], ,
$X_LIBS $X_PRELIBS -lssl $X_EXTRA_LIBS)
fi
AH_TEMPLATE(HAVE_LIBCRYPTO, [openssl libcrypto library present]) AH_TEMPLATE(HAVE_LIBCRYPTO, [openssl libcrypto library present])
AC_ARG_WITH(crypto, AC_ARG_WITH(crypto,
[ --without-crypto disable support for openssl libcrypto],,) [ --without-crypto disable support for openssl libcrypto],,)
# some OS's need both -lssl and -lcrypto
if test "x$HAVE_LIBSSL" = "xtrue"; then AH_TEMPLATE(HAVE_LIBSSL, [openssl libssl library present])
AC_CHECK_LIB(crypto, RAND_load_file, AC_ARG_WITH(ssl,
X_PRELIBS="$X_PRELIBS -lcrypto" [ --without-ssl disable support for openssl libssl],,)
[AC_DEFINE(HAVE_LIBSSL) HAVE_LIBSSL="true"], ,
$X_LIBS $X_PRELIBS -lcrypto $X_EXTRA_LIBS) if test "x$with_crypto" != "xno" -a "x$with_ssl" != "xno"; then
AC_CHECK_LIB(crypto, RAND_file_name,
[AC_DEFINE(HAVE_LIBCRYPTO) HAVE_LIBCRYPTO="true"], ,)
fi fi
if test "x$with_ssl" != "xno"; then
if test "x$HAVE_LIBCRYPTO" = "xtrue"; then
AC_CHECK_LIB(ssl, SSL_library_init,
X_PRELIBS="$X_PRELIBS -lssl -lcrypto"
[AC_DEFINE(HAVE_LIBSSL) HAVE_LIBSSL="true"], ,
-lcrypto)
else
AC_CHECK_LIB(ssl, SSL_library_init,
X_PRELIBS="$X_PRELIBS -lssl"
[AC_DEFINE(HAVE_LIBSSL) HAVE_LIBSSL="true"], ,)
fi
fi
X_LIBS="$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS" X_LIBS="$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS"
fi fi
@ -452,6 +458,7 @@ AC_CONFIG_FILES([Makefile
examples/Makefile examples/Makefile
vncterm/Makefile vncterm/Makefile
classes/Makefile classes/Makefile
classes/ssl/Makefile
libvncclient/Makefile libvncclient/Makefile
client_examples/Makefile client_examples/Makefile
test/Makefile test/Makefile

@ -67,7 +67,11 @@
"<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \ "<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \
"<BODY><H1>Invalid request</H1></BODY>\n" "<BODY><H1>Invalid request</H1></BODY>\n"
#define OK_STR "HTTP/1.0 200 OK\nContent-Type: text/html\r\n\r\n" #if 1
#define OK_STR "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
#else
#define OK_STR "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"
#endif
static void httpProcessInput(rfbScreenInfoPtr screen); static void httpProcessInput(rfbScreenInfoPtr screen);
static rfbBool compareAndSkip(char **ptr, const char *str); static rfbBool compareAndSkip(char **ptr, const char *str);

@ -58,6 +58,12 @@ cp classes/Makefile.am classes/Makefile.am.LibVNCServer
echo 'pkgdatadir = $(datadir)/@PACKAGE@/classes' >> classes/Makefile.am echo 'pkgdatadir = $(datadir)/@PACKAGE@/classes' >> classes/Makefile.am
echo 'pkgdata_DATA=VncViewer.jar index.vnc' >> classes/Makefile.am echo 'pkgdata_DATA=VncViewer.jar index.vnc' >> classes/Makefile.am
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
mv acinclude.m4 acinclude.m4.LibVNCServer mv acinclude.m4 acinclude.m4.LibVNCServer
cat acinclude.m4.LibVNCServer | \ cat acinclude.m4.LibVNCServer | \
@ -65,7 +71,7 @@ sed -e "s/^\(_PKG.*\)\$PACKAGE\(.*\)$/\1LibVNCServer\2/" \
> acinclude.m4 > acinclude.m4
make x11vnc-${VERSION}.tar.gz make x11vnc-${VERSION}.tar.gz
for f in configure.ac Makefile.am libvncserver/Makefile.am classes/Makefile.am acinclude.m4 README; do for f in configure.ac Makefile.am libvncserver/Makefile.am classes/Makefile.am classes/ssl/Makefile.am acinclude.m4 README; do
mv -f $f.LibVNCServer $f mv -f $f.LibVNCServer $f
done done

@ -1,3 +1,11 @@
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
port. Look for classes/ssl under -http. add Java URL messages
to final output lines. make -inetd work with -ssl (even for
https). fix -unixpw login prompt under -scale. guard against
clientData = NULL.
2006-03-11 Karl Runge <runge@karlrunge.com> 2006-03-11 Karl Runge <runge@karlrunge.com>
* x11vnc: add -ssl mode using libssl. Include Xdummy in misc. * x11vnc: add -ssl mode using libssl. Include Xdummy in misc.
a few more macros for smallerfoot, etc. a few more macros for smallerfoot, etc.

File diff suppressed because it is too large Load Diff

@ -135,7 +135,7 @@ void clean_up_exit (int ret) {
} }
stop_stunnel(); stop_stunnel();
if (use_openssl) { if (use_openssl) {
ssh_helper_pid(0, 0); /* killall */ ssl_helper_pid(0, 0); /* killall */
} }
X_LOCK; X_LOCK;

@ -32,6 +32,7 @@ void close_all_clients(void);
void close_clients(char *str); void close_clients(char *str);
void set_client_input(char *str); void set_client_input(char *str);
void set_child_info(void); void set_child_info(void);
void client_gone(rfbClientPtr client);
void reverse_connect(char *str); void reverse_connect(char *str);
void set_vnc_connect_prop(char *str); void set_vnc_connect_prop(char *str);
void read_vnc_connect_prop(int); void read_vnc_connect_prop(int);
@ -48,7 +49,6 @@ void check_new_clients(void);
static rfbClientPtr *client_match(char *str); static rfbClientPtr *client_match(char *str);
static int run_user_command(char *cmd, rfbClientPtr client, char *mode); static int run_user_command(char *cmd, rfbClientPtr client, char *mode);
static void free_client_data(rfbClientPtr client); static void free_client_data(rfbClientPtr client);
static void client_gone(rfbClientPtr client);
static int check_access(char *addr); static int check_access(char *addr);
static void ugly_geom(char *p, int *x, int *y); static void ugly_geom(char *p, int *x, int *y);
static int ugly_window(char *addr, char *userhost, int X, int Y, static int ugly_window(char *addr, char *userhost, int X, int Y,
@ -113,6 +113,9 @@ char *list_clients(void) {
iter = rfbGetClientIterator(screen); iter = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(iter)) ) { while( (cl = rfbClientIteratorNext(iter)) ) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
if (*list != '\0') { if (*list != '\0') {
strcat(list, ","); strcat(list, ",");
} }
@ -199,6 +202,9 @@ static rfbClientPtr *client_match(char *str) {
unsigned int in; unsigned int in;
int id; int id;
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
if (sscanf(str, "0x%x", &in) != 1) { if (sscanf(str, "0x%x", &in) != 1) {
if (hex_warn++) { if (hex_warn++) {
continue; continue;
@ -289,6 +295,9 @@ void set_client_input(char *str) {
cp = cl_list; cp = cl_list;
while (*cp) { while (*cp) {
ClientData *cd = (ClientData *) (*cp)->clientData; ClientData *cd = (ClientData *) (*cp)->clientData;
if (! cd) {
continue;
}
cd->input[0] = '\0'; cd->input[0] = '\0';
strcat(cd->input, "_"); strcat(cd->input, "_");
strcat(cd->input, val); strcat(cd->input, val);
@ -543,7 +552,7 @@ static int accepted_client = 0;
/* /*
* callback for when a client disconnects * callback for when a client disconnects
*/ */
static void client_gone(rfbClientPtr client) { void client_gone(rfbClientPtr client) {
ClientData *cd = NULL; ClientData *cd = NULL;
client_count--; client_count--;
@ -571,15 +580,16 @@ static void client_gone(rfbClientPtr client) {
} }
if (client->clientData) { if (client->clientData) {
cd = (ClientData *) client->clientData; cd = (ClientData *) client->clientData;
if (cd->ssh_helper_pid > 0) { if (cd->ssl_helper_pid > 0) {
int status; int status;
rfbLog("sending SIGTERM to ssh_helper_pid: %d\n", rfbLog("sending SIGTERM to ssl_helper_pid: %d\n",
cd->ssh_helper_pid); cd->ssl_helper_pid);
kill(cd->ssh_helper_pid, SIGTERM); kill(cd->ssl_helper_pid, SIGTERM);
usleep(200*1000);
#if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID #if LIBVNCSERVER_HAVE_SYS_WAIT_H && LIBVNCSERVER_HAVE_WAITPID
waitpid(cd->ssh_helper_pid, &status, WNOHANG); waitpid(cd->ssl_helper_pid, &status, WNOHANG);
#endif #endif
ssh_helper_pid(cd->ssh_helper_pid, -1); /* delete */ ssl_helper_pid(cd->ssl_helper_pid, -1); /* delete */
} }
} }
if (gone_cmd && *gone_cmd != '\0') { if (gone_cmd && *gone_cmd != '\0') {
@ -1486,13 +1496,13 @@ static int do_reverse_connect(char *str) {
} }
if (inetd && unixpw) { if (inetd && unixpw) {
if(strcmp(host, "localhost") && strcmp(host, "127.0.0.1")) { if(strcmp(host, "localhost") && strcmp(host, "127.0.0.1")) {
if (! getenv("UNIXPW_DISABLE_LOCALHOST")) { if (! getenv("UNIXPW_DISABLE_LOCALHOST")) {
rfbLog("reverse_connect: in -inetd only localhost\n"); rfbLog("reverse_connect: in -inetd only localhost\n");
rfbLog("connections allowed under -unixpw\n"); rfbLog("connections allowed under -unixpw\n");
return 0; return 0;
}
} }
}
if (! getenv("UNIXPW_DISABLE_SSL") && ! have_ssh_env()) { if (! getenv("UNIXPW_DISABLE_SSL") && ! have_ssh_env()) {
rfbLog("reverse_connect: in -inetd stunnel/ssh\n"); rfbLog("reverse_connect: in -inetd stunnel/ssh\n");
rfbLog("required under -unixpw\n"); rfbLog("required under -unixpw\n");
@ -1839,7 +1849,7 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
} }
clients_served++; clients_served++;
if (0) fprintf(stderr, "new_client: %s %d\n", client->host, clients_served); if (getenv("NEW_CLIENT")) fprintf(stderr, "new_client: %s %d\n", client->host, clients_served);
if (use_openssl || use_stunnel) { if (use_openssl || use_stunnel) {
if (! ssl_initialized) { if (! ssl_initialized) {
@ -1881,11 +1891,11 @@ if (0) fprintf(stderr, "new_client: %s %d\n", client->host, clients_served);
cd->input[0] = '-'; cd->input[0] = '-';
cd->login_viewonly = -1; cd->login_viewonly = -1;
cd->login_time = time(0); cd->login_time = time(0);
cd->ssh_helper_pid = 0; cd->ssl_helper_pid = 0;
if (use_openssl && openssl_last_helper_pid) { if (use_openssl && openssl_last_helper_pid) {
if (0) fprintf(stderr, "SET ssh_helper_pid: %d\n", openssl_last_helper_pid); if (0) fprintf(stderr, "SET ssl_helper_pid: %d\n", openssl_last_helper_pid);
cd->ssh_helper_pid = openssl_last_helper_pid; cd->ssl_helper_pid = openssl_last_helper_pid;
openssl_last_helper_pid = 0; openssl_last_helper_pid = 0;
} }
@ -2131,6 +2141,10 @@ void check_new_clients(void) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
char *s; char *s;
if (! cd) {
continue;
}
if (cd->login_viewonly < 0) { if (cd->login_viewonly < 0) {
/* this is a general trigger to initialize things */ /* this is a general trigger to initialize things */
if (cl->viewOnly) { if (cl->viewOnly) {

@ -17,6 +17,7 @@ extern void close_all_clients(void);
extern void close_clients(char *str); extern void close_clients(char *str);
extern void set_client_input(char *str); extern void set_client_input(char *str);
extern void set_child_info(void); extern void set_child_info(void);
extern void client_gone(rfbClientPtr client);
extern void reverse_connect(char *str); extern void reverse_connect(char *str);
extern void set_vnc_connect_prop(char *str); extern void set_vnc_connect_prop(char *str);
extern void read_vnc_connect_prop(int); extern void read_vnc_connect_prop(int);

@ -799,6 +799,7 @@ static void setup_cursors(void) {
UNLOCK(screen->cursorMutex); UNLOCK(screen->cursorMutex);
} }
rfbLog(" done.\n"); rfbLog(" done.\n");
rfbLog("\n");
} }
void setup_cursors_and_push(void) { void setup_cursors_and_push(void) {
@ -1541,6 +1542,9 @@ void restore_cursor_shape_updates(rfbScreenInfoPtr s) {
int changed = 0; int changed = 0;
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
if (cd->had_cursor_shape_updates) { if (cd->had_cursor_shape_updates) {
rfbLog("restoring enableCursorShapeUpdates for client" rfbLog("restoring enableCursorShapeUpdates for client"
" 0x%x\n", cl); " 0x%x\n", cl);
@ -1578,14 +1582,18 @@ void disable_cursor_shape_updates(rfbScreenInfoPtr s) {
cd = (ClientData *) cl->clientData; cd = (ClientData *) cl->clientData;
if (cl->enableCursorShapeUpdates) { if (cl->enableCursorShapeUpdates) {
cd->had_cursor_shape_updates = 1; if (cd) {
cd->had_cursor_shape_updates = 1;
}
count++; count++;
if (debug_pointer) { if (debug_pointer) {
rfbLog("%s disable HCSU\n", cl->host); rfbLog("%s disable HCSU\n", cl->host);
} }
} }
if (cl->enableCursorPosUpdates) { if (cl->enableCursorPosUpdates) {
cd->had_cursor_pos_updates = 1; if (cd) {
cd->had_cursor_pos_updates = 1;
}
count++; count++;
if (debug_pointer) { if (debug_pointer) {
rfbLog("%s disable HCPU\n", cl->host); rfbLog("%s disable HCPU\n", cl->host);

@ -19,6 +19,8 @@ void print_help(int mode) {
"\n" "\n"
"x11vnc: allow VNC connections to real X11 displays. %s\n" "x11vnc: allow VNC connections to real X11 displays. %s\n"
"\n" "\n"
"(type \"x11vnc -opts\" to just list the options.)\n"
"\n"
"Typical usage is:\n" "Typical usage is:\n"
"\n" "\n"
" Run this command in a shell on the remote machine \"far-host\"\n" " Run this command in a shell on the remote machine \"far-host\"\n"
@ -423,20 +425,22 @@ void print_help(int mode) {
" send one before a 25 second timeout. Existing clients\n" " send one before a 25 second timeout. Existing clients\n"
" are view-only during this period.\n" " are view-only during this period.\n"
"\n" "\n"
" Since the detailed behavior of su(1) can vary from OS\n" " Since the detailed behavior of su(1) can vary from\n"
" to OS and for local configurations, please test the mode\n" " OS to OS and for local configurations, test the mode\n"
" carefully on your systems before using it in production.\n" " carefully on your systems before using it in production.\n"
" E.g. try different combinations of valid/invalid\n" " Test different combinations of valid/invalid usernames\n"
" usernames and valid/invalid passwords to see if it\n" " and valid/invalid passwords to see if it behaves as\n"
" behaves correctly. x11vnc will be conservative and\n" " expected. x11vnc will attempt to be conservative and\n"
" reject a user if anything abnormal occurs.\n" " reject a login if anything abnormal occurs.\n"
" \n" "\n"
" For example, on FreeBSD and the other BSD's by default\n" " On FreeBSD and the other BSD's by default it is\n"
" it is impossible for the user running x11vnc to validate\n" " impossible for the user running x11vnc to validate\n"
" his *own* password via su(1) (evidently commenting\n" " his *own* password via su(1) (evidently commenting out\n"
" out the pam_self.so entry in /etc/pam.d/su eliminates\n" " the pam_self.so entry in /etc/pam.d/su eliminates this\n"
" the problem). So the x11vnc login will always fail for\n" " problem). So the x11vnc login will always *fail* for\n"
" this case. A possible workaround would be to start\n" " this case (even when the correct password is supplied).\n"
"\n"
" A possible workaround for this would be to start\n"
" x11vnc as root with the \"-users +nobody\" option to\n" " x11vnc as root with the \"-users +nobody\" option to\n"
" immediately switch to user nobody. Another source of\n" " immediately switch to user nobody. Another source of\n"
" problems are PAM modules that prompt for extra info,\n" " problems are PAM modules that prompt for extra info,\n"
@ -459,48 +463,50 @@ void print_help(int mode) {
" -stunnel SSL mode be used for encryption over the\n" " -stunnel SSL mode be used for encryption over the\n"
" network.(see the description of -stunnel below).\n" " network.(see the description of -stunnel below).\n"
"\n" "\n"
" As a convenience, if you ssh(1) in and start x11vnc it\n" " Note: as a convenience, if you ssh(1) in and start\n"
" will check if the environment variable SSH_CONNECTION\n" " x11vnc it will check if the environment variable\n"
" is set and appears reasonable. If it does, then the\n" " SSH_CONNECTION is set and appears reasonable. If it\n"
" -ssl or -stunnel requirement will be dropped since it is\n" " does, then the -ssl or -stunnel requirement will be\n"
" assumed you are using ssh for the encrypted tunnelling.\n" " dropped since it is assumed you are using ssh for the\n"
" -localhost is still enforced. Use -ssl or -stunnel to\n" " encrypted tunnelling. -localhost is still enforced.\n"
" force SSL usage for this case.\n" " Use -ssl or -stunnel to force SSL usage even if\n"
" SSH_CONNECTION is set.\n"
"\n" "\n"
" To override these restrictions you can set environment\n" " To override the above restrictions you can set\n"
" variables before starting x11vnc:\n" " environment variables before starting x11vnc:\n"
"\n" "\n"
" Set UNIXPW_DISABLE_SSL=1 to disable requiring either\n" " Set UNIXPW_DISABLE_SSL=1 to disable requiring either\n"
" -ssl or -stunnel. Evidently you will be using a\n" " -ssl or -stunnel. Evidently you will be using a\n"
" different method to encrypt the data between the\n" " different method to encrypt the data between the\n"
" vncviewer and x11vnc: e.g. ssh(1) or a VPN. Note that\n" " vncviewer and x11vnc: perhaps ssh(1) or an IPSEC VPN.\n"
" use of -localhost with ssh(1) is roughly the same as\n" "\n"
" requiring a Unix user login (since a Unix password or\n" " Note that use of -localhost with ssh(1) is roughly\n"
" the user's public key authentication is used by sshd on\n" " the same as requiring a Unix user login (since a Unix\n"
" the machine where x11vnc runs and only local connections\n" " password or the user's public key authentication is\n"
" are accepted)\n" " used by sshd on the machine where x11vnc runs and only\n"
" local connections from that machine are accepted)\n"
"\n" "\n"
" Set UNIXPW_DISABLE_LOCALHOST=1 to disable the -localhost\n" " Set UNIXPW_DISABLE_LOCALHOST=1 to disable the -localhost\n"
" requirement in Method 2). One should never do this\n" " requirement in Method 2). One should never do this\n"
" (i.e. allow the Unix passwords to be sniffed on the\n" " (i.e. allow the Unix passwords to be sniffed on the\n"
" network).\n" " network).\n"
"\n" "\n"
" Regarding reverse connections (e.g. -R connect:host),\n" " Regarding reverse connections (e.g. -R connect:host\n"
" if the -localhost constraint is in effect then reverse\n" " and -connect host), when the -localhost constraint is\n"
" connections can only be used to connect to the same\n" " in effect then reverse connections can only be used\n"
" machine x11vnc is running on (default port 5500).\n" " to connect to the same machine x11vnc is running on\n"
" Please use a ssh or stunnel port redirection to the\n" " (default port 5500). Please use a ssh or stunnel port\n"
" viewer machine to tunnel the reverse connection over\n" " redirection to the viewer machine to tunnel the reverse\n"
" an encrypted channel. Note that in -ssl mode reverse\n" " connection over an encrypted channel. Note that in -ssl\n"
" connection are disabled.\n" " mode reverse connection are disabled (see below).\n"
"\n" "\n"
" XXX -inetd + -ssl\n" " In -inetd mode the Method 1) will be enforced (not\n"
" In -inetd mode the two settings are attempted to be\n" " Method 2). With -ssl in effect reverse connections\n"
" enforced for reverse connections. Be sure to also\n" " are disabled. If you override this via env. var, be\n"
" use encryption from the viewer to inetd since x11vnc\n" " sure to also use encryption from the viewer to inetd.\n"
" cannot guess easily if it is encrpyted. Tip: you can\n" " Tip: you can also have your own stunnel spawn x11vnc\n"
" also have your own stunnel spawn x11vnc in -inetd mode\n" " in -inetd mode (thereby bypassing inetd). See the FAQ\n"
" (i.e. bypassing inetd). See the FAQ for details.\n" " for details.\n"
"\n" "\n"
" The user names in the comma separated [list] can have\n" " The user names in the comma separated [list] can have\n"
" per-user options after a \":\", e.g. \"fred:opts\"\n" " per-user options after a \":\", e.g. \"fred:opts\"\n"
@ -515,22 +521,24 @@ void print_help(int mode) {
" Use \"deny\" to explicitly deny some users if you use\n" " Use \"deny\" to explicitly deny some users if you use\n"
" \"*\" to set a global option.\n" " \"*\" to set a global option.\n"
"\n" "\n"
" There are also some tools for testing password if [list]\n" " There are also some utilities for testing password\n"
" starts with the \"%\" character. See the quick_pw()\n" " if [list] starts with the \"%\" character. See the\n"
" function for details.\n" " quick_pw() function in the source for details.\n"
"\n" "\n"
"-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n" "-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n"
" use the traditional getpwnam(3) + crypt(3) method\n" " use the traditional getpwnam(3) + crypt(3) method to\n"
" instead. This requires that the encrpyted passwords\n" " verify passwords instead. This requires that the\n"
" be readable. Passwords stored in /etc/shadow will\n" " encrpyted passwords be readable. Passwords stored\n"
" be inaccessible unless run as root. This is called\n" " in /etc/shadow will be inaccessible unless x11vnc\n"
" \"NIS\" mode simply because in most NIS setups the\n" " is run as root.\n"
" user encrypted passwords are accessible (e.g. \"ypcat\n" "\n"
" passwd\"). NIS is not required for this mode to work\n" " This is called \"NIS\" mode simply because in most\n"
" (only that getpwnam(3) return the encrpyted password\n" " NIS setups the user encrypted passwords are accessible\n"
" is required), but it is unlikely it will work for any\n" " (e.g. \"ypcat passwd\"). NIS is not required for this\n"
" other environment. All of the -unixpw options and\n" " mode to work (only that getpwnam(3) return the encrpyted\n"
" contraints apply.\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"
"\n" "\n"
"-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n" "-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n"
" built-in encrypted SSL tunnel between VNC viewers and\n" " built-in encrypted SSL tunnel between VNC viewers and\n"
@ -539,30 +547,33 @@ void print_help(int mode) {
" with libssl support it will exit immediately when -ssl\n" " with libssl support it will exit immediately when -ssl\n"
" is prescribed.\n" " is prescribed.\n"
"\n" "\n"
" [pem] is optional, use \"-ssl /path/to/mycert.pem\" to\n" " [pem] is optional, use \"-ssl /path/to/mycert.pem\"\n"
" specify a PEM certificate file to use to identify and\n" " to specify a PEM certificate file to use to identify\n"
" provide a key for this server.\n" " and provide a key for this server. See openssl(1)\n"
"\n" " for what a PEM can be.\n"
" Connecting VNC viewer SSL tunnels can authenticate\n" "\n"
" this server if they have the public key part of the\n" " Connecting VNC viewer SSL tunnels can optionally\n"
" certificate (or a common certificate authority, CA,\n" " authenticate this server if they have the public\n"
" verifies this server's cert). This is used to prevent\n" " key part of the certificate (or a common certificate\n"
" man-in-the-middle attacks. Otherwise, if the VNC viewer\n" " authority, CA, is a more sophisicated way to verify\n"
" accepts this server's key without verification, at\n" " this server's cert). This is used to prevent\n"
" least the traffic is protected from passive sniffing\n" " man-in-the-middle attacks. Otherwise, if the VNC\n"
" on the network.\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"
"\n" "\n"
" If [pem] is not supplied and the openssl(1) utility\n" " If [pem] is not supplied and the openssl(1) utility\n"
" command exists in PATH, then a temporary, self-signed\n" " command exists in PATH, then a temporary, self-signed\n"
" certificate will be generated for this session (this\n" " certificate will be generated for this session (this\n"
" may take 5-20 seconds on slow machines). If openssl(1)\n" " may take 5-30 seconds on slow machines). If openssl(1)\n"
" cannot be used to generate a temporary certificate\n" " cannot be used to generate a temporary certificate\n"
" x11vnc exits immediately.\n" " x11vnc exits immediately.\n"
"\n" "\n"
" If successful in using openssl(1) to generate a\n" " If successful in using openssl(1) to generate a\n"
" certificate, the public part of it will be displayed\n" " temporary certificate, the public part of it will be\n"
" to stdout (e.g. one could copy it to the client-side\n" " displayed to stderr (e.g. one could copy it to the\n"
" to provide authentication of the server to VNC viewers.)\n" " client-side to provide authentication of the server to\n"
" VNC viewers.)\n"
"\n" "\n"
" Set the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc\n" " Set the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc\n"
" print out the entire certificate, including the PRIVATE\n" " print out the entire certificate, including the PRIVATE\n"
@ -572,20 +583,23 @@ void print_help(int mode) {
" will be printed to stderr (so one could move it to a\n" " will be printed to stderr (so one could move it to a\n"
" safe place for reuse).\n" " safe place for reuse).\n"
"\n" "\n"
" Reverse connections are disabled in -ssl\n" " Reverse connections are disabled in -ssl mode because\n"
" mode because the data cannot be encrypted.\n" " there is no way to ensure that data channel will\n"
" Set X11VNC_SSL_ALLOW_REVERSE=1 to override this.\n" " be encrypted. Set X11VNC_SSL_ALLOW_REVERSE=1 to\n"
" override this.\n"
"\n" "\n"
" Your VNC viewer will also need to be able to connect\n" " Your VNC viewer will also need to be able to connect\n"
" via SSL. See the discussion below under -stunnel and\n" " via SSL. See the discussion below under -stunnel\n"
" the FAQ for how this might be achieved. E.g. on Unix it\n" " and the FAQ for how this might be achieved. E.g. on\n"
" is easy to write a shell script that starts up stunnel\n" " Unix it is easy to write a shell script that starts up\n"
" and then vncviewer.\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"
"\n" "\n"
"-sslverify [path] For either of the -ssl or -stunnel modes, use [path]\n" "-sslverify [path] For either of the -ssl or -stunnel modes, use [path]\n"
" to provide certificates to authenticate incoming VNC\n" " to provide certificates to authenticate incoming VNC\n"
" client connections. This can be used as a method to\n" " client connections. This can be used as a method to\n"
" replace standard password authentication.\n" " replace standard password authentication of clients.\n"
"\n" "\n"
" If [path] is a directory it contains the client (or CA)\n" " If [path] is a directory it contains the client (or CA)\n"
" certificates in separate files. If [path] is a file, it\n" " certificates in separate files. If [path] is a file, it\n"
@ -595,37 +609,44 @@ void print_help(int mode) {
"\n" "\n"
" To create certificates for all sorts of authentications\n" " To create certificates for all sorts of authentications\n"
" (clients, servers, via CA, etc) see the openssl(1)\n" " (clients, servers, via CA, etc) see the openssl(1)\n"
" command. Of particular usefulness is the x509\n" " command. Of particular usefulness is the \"x509\"\n"
" subcommand of openssl(1).\n" " subcommand of openssl(1).\n"
"\n" "\n"
"-stunnel [pem] Use the stunnel(8) (www.stunnel.org) to provide\n" "-stunnel [pem] Use the stunnel(8) (www.stunnel.org) to provide an\n"
" an encrypted SSL tunnel between viewers and x11vnc.\n" " encrypted SSL tunnel between viewers and x11vnc. This\n"
" This requires stunnel to be installed on the system and\n" " was implemented prior to the integrated -ssl encrpytion.\n"
" available via PATH (n.b. stunnel is often installed in\n" " It works well. This requires stunnel to be installed\n"
" sbin directories). Version 4.x of stunnel is assumed\n" " on the system and available via PATH (n.b. stunnel is\n"
" (but see -stunnel3 below.)\n" " often installed in sbin directories). Version 4.x of\n"
" stunnel is assumed (but see -stunnel3 below.)\n"
"\n" "\n"
" [pem] is optional, use \"-stunnel /path/to/stunnel.pem\"\n" " [pem] is optional, use \"-stunnel /path/to/stunnel.pem\"\n"
" to specify a PEM certificate file to pass to stunnel.\n" " to specify a PEM certificate file to pass to stunnel.\n"
" Whether one is needed or not depends on your stunnel\n" " Whether one is needed or not depends on your stunnel\n"
" configuration. stunnel often generates one at install\n" " configuration. stunnel often generates one at install\n"
" time.\n" " time. See the stunnel documentation for details.\n"
"\n" "\n"
" stunnel is started up as a child process of x11vnc and\n" " stunnel is started up as a child process of x11vnc and\n"
" any SSL connections stunnel receives are decrypted and\n" " any SSL connections stunnel receives are decrypted and\n"
" sent to x11vnc over a local socket. The strings\n" " sent to x11vnc over a local socket. The strings\n"
" \"The SSL VNC desktop is ...\" and \"SSLPORT=...\"\n" " \"The SSL VNC desktop is ...\" and \"SSLPORT=...\"\n"
" are printed out at startup.\n" " are printed out at startup to indicate this.\n"
"\n" "\n"
" The -localhost option is enforced by default to\n" " The -localhost option is enforced by default\n"
" avoid people routing around the SSL channel. Set\n" " to avoid people routing around the SSL channel.\n"
" STUNNEL_DISABLE_LOCALHOST=1 to disable the requirement.\n" " Set STUNNEL_DISABLE_LOCALHOST=1 before starting x11vnc\n"
" to disable the requirement.\n"
"\n" "\n"
" Your VNC viewer will also need to be able to connect\n" " Your VNC viewer will also need to be able to connect via\n"
" via SSL. Unfortunately not too many do this. UltraVNC\n" " SSL. Unfortunately not too many do this. UltraVNC has\n"
" seems to have an encryption plugin. It is not too\n" " an encryption plugin but it does not seem to be SSL.\n"
" difficult to set up an stunnel or other SSL tunnel on\n" "\n"
" the viewer side.\n" " In the x11vnc distribution, a patched TightVNC Java\n"
" applet is provided in classes/ssl that does SSL\n"
" connections (only).\n"
"\n"
" It is also not too difficult to set up an stunnel or\n"
" other SSL tunnel on the viewer side.\n"
"\n" "\n"
" A simple example on Unix using stunnel 3.x is:\n" " A simple example on Unix using stunnel 3.x is:\n"
"\n" "\n"
@ -639,6 +660,35 @@ void print_help(int mode) {
"-stunnel3 [pem] Use version 3.x stunnel command line syntax instead of\n" "-stunnel3 [pem] Use version 3.x stunnel command line syntax instead of\n"
" version 4.x\n" " version 4.x\n"
"\n" "\n"
"-https [port] Choose a separate HTTPS port (-ssl mode only).\n"
"\n"
" In -ssl mode, it turns out you can use the\n"
" single VNC port (e.g. 5900) for both VNC and HTTPS\n"
" connections. (HTTPS is used to retrieve a SSL-aware\n"
" VncViewer.jar applet that is provided with x11vnc).\n"
" Since both use SSL the implementation was extended to\n"
" detect if HTTP traffic (i.e. GET) is taking place and\n"
" handle it accordingly. The URL would be, e.g.:\n"
"\n"
" https://mymachine.org:5900/\n"
"\n"
" This is convenient for firewalls, etc, because only one\n"
" port needs to be allowed in. However, this heuristic\n"
" adds a few seconds delay to each connection and can be\n"
" unreliable (especially if the user takes much time to\n"
" ponder the Certificate dialogs in his browser, Java VM,\n"
" or VNC Viewer applet. That's right 3 separate \"Are\n"
" you sure you want to connect\" dialogs!)\n"
"\n"
" So use the -https option to provide a separate, more\n"
" reliable HTTPS port that x11vnc will listen on. If\n"
" [port] is not provided (or is 0), one is autoselected.\n"
" The URL to use is printed out at startup.\n"
"\n"
" The SSL Java applet directory is specified via the\n"
" -httpdir option. If not supplied it will try to guess\n"
" the directory as though the -http option was supplied.\n"
"\n"
"-usepw If no other password method was supplied on the command\n" "-usepw If no other password method was supplied on the command\n"
" line, first look for ~/.vnc/passwd and if found use it\n" " line, first look for ~/.vnc/passwd and if found use it\n"
" with -rfbauth; next, look for ~/.vnc/passwdfile and\n" " with -rfbauth; next, look for ~/.vnc/passwdfile and\n"
@ -844,9 +894,10 @@ void print_help(int mode) {
" string \"noptr\" the mouse pointer will not be allowed\n" " string \"noptr\" the mouse pointer will not be allowed\n"
" to go into a blacked out region.\n" " to go into a blacked out region.\n"
"-xinerama If your screen is composed of multiple monitors\n" "-xinerama If your screen is composed of multiple monitors\n"
" glued together via XINERAMA, and that screen is\n" "-noxinerama glued together via XINERAMA, and that screen is\n"
" not a rectangle this option will try to guess the\n" " not a rectangle this option will try to guess the\n"
" areas to black out (if your system has libXinerama).\n" " areas to black out (if your system has libXinerama).\n"
" default: %s\n"
"\n" "\n"
" In general, we have noticed on XINERAMA displays you\n" " In general, we have noticed on XINERAMA displays you\n"
" may need to use the \"-xwarppointer\" option if the mouse\n" " may need to use the \"-xwarppointer\" option if the mouse\n"
@ -2261,9 +2312,9 @@ void print_help(int mode) {
" http_url auth xauth users rootshift clipshift\n" " http_url auth xauth users rootshift clipshift\n"
" scale_str scaled_x scaled_y scale_numer scale_denom\n" " scale_str scaled_x scaled_y scale_numer scale_denom\n"
" scale_fac scaling_blend scaling_nomult4 scaling_pad\n" " scale_fac scaling_blend scaling_nomult4 scaling_pad\n"
" scaling_interpolate inetd privremote unsafe safer\n" " scaling_interpolate inetd privremote unsafe safer nocmds\n"
" nocmds passwdfile unixpw unixpw_nis unixpw_list ssl\n" " passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem\n"
" ssl_pem sslverify stunnel stunnel_pem usepw using_shm\n" " sslverify stunnel stunnel_pem https usepw using_shm\n"
" logfile o flag rc norc h help V version lastmod bg\n" " logfile o flag rc norc h help V version lastmod bg\n"
" sigpipe threads readrate netrate netlatency pipeinput\n" " sigpipe threads readrate netrate netlatency pipeinput\n"
" clients client_count pid ext_xtest ext_xtrap ext_xrecord\n" " clients client_count pid ext_xtest ext_xtrap ext_xrecord\n"
@ -2364,7 +2415,7 @@ void print_help(int mode) {
strncpy(tmp, p, w); strncpy(tmp, p, w);
fprintf(stderr, " %s", tmp); fprintf(stderr, " %s", tmp);
l++; l++;
if (l % 2 == 0) { if (l % 3 == 0) {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
} }
@ -2381,6 +2432,7 @@ void print_help(int mode) {
view_only ? "on":"off", view_only ? "on":"off",
shared ? "on":"off", shared ? "on":"off",
vnc_connect ? "-vncconnect":"-novncconnect", vnc_connect ? "-vncconnect":"-novncconnect",
xinerama ? "-xinerama":"-noxinerama",
use_modifier_tweak ? "-modtweak":"-nomodtweak", use_modifier_tweak ? "-modtweak":"-nomodtweak",
skip_duplicate_key_events ? "-skip_dups":"-noskip_dups", skip_duplicate_key_events ? "-skip_dups":"-noskip_dups",
add_keysyms ? "-add_keysyms":"-noadd_keysyms", add_keysyms ? "-add_keysyms":"-noadd_keysyms",

@ -2098,6 +2098,16 @@ void initialize_allowed_input(void) {
while( (cl = rfbClientIteratorNext(iter)) ) { while( (cl = rfbClientIteratorNext(iter)) ) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
#if 0
rfbLog("cd: %p\n", cd);
rfbLog("cd->input: %s\n", cd->input);
rfbLog("cd->login_viewonly: %d\n", cd->login_viewonly);
rfbLog("allowed_input_view_only: %s\n", allowed_input_view_only);
#endif
if (cd->input[0] == '=') { if (cd->input[0] == '=') {
; /* custom setting */ ; /* custom setting */
} else if (cd->login_viewonly) { } else if (cd->login_viewonly) {
@ -2365,6 +2375,10 @@ void get_allowed_input(rfbClientPtr client, allowed_input_t *input) {
} }
cd = (ClientData *) client->clientData; cd = (ClientData *) client->clientData;
if (! cd) {
return;
}
if (cd->input[0] != '-') { if (cd->input[0] != '-') {
str = cd->input; str = cd->input;
@ -2398,7 +2412,7 @@ void get_allowed_input(rfbClientPtr client, allowed_input_t *input) {
/* for -pipeinput mode */ /* for -pipeinput mode */
static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
int can_input = 0, uid; int can_input = 0, uid = 0;
allowed_input_t input; allowed_input_t input;
char *name; char *name;
ClientData *cd = (ClientData *) client->clientData; ClientData *cd = (ClientData *) client->clientData;
@ -2413,7 +2427,9 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
can_input = 1; /* XXX distinguish later */ can_input = 1; /* XXX distinguish later */
} }
} }
uid = cd->uid; if (cd) {
uid = cd->uid;
}
if (! can_input) { if (! can_input) {
uid = -uid; uid = -uid;
} }

@ -23,6 +23,7 @@ int stunnel_port = 0;
char *stunnel_pem = NULL; char *stunnel_pem = NULL;
int use_openssl = 0; int use_openssl = 0;
char *openssl_pem = NULL; char *openssl_pem = NULL;
int https_port_num = -1;
char *ssl_verify = NULL; char *ssl_verify = NULL;
int ssl_initialized = 0; int ssl_initialized = 0;
int usepw = USEPW; int usepw = USEPW;
@ -124,7 +125,7 @@ int debug_grabs = 0;
int debug_sel = 0; int debug_sel = 0;
int xtrap_input = 0; /* -xtrap for user input insertion */ int xtrap_input = 0; /* -xtrap for user input insertion */
int xinerama = 0; /* -xinerama */ int xinerama = XINERAMA; /* -xinerama */
int xrandr = 0; /* -xrandr */ int xrandr = 0; /* -xrandr */
char *xrandr_mode = NULL; char *xrandr_mode = NULL;
char *pad_geometry = NULL; char *pad_geometry = NULL;

@ -23,6 +23,7 @@ extern int stunnel_port;
extern char *stunnel_pem; extern char *stunnel_pem;
extern int use_openssl; extern int use_openssl;
extern char *openssl_pem; extern char *openssl_pem;
extern int https_port_num;
extern char *ssl_verify; extern char *ssl_verify;
extern int ssl_initialized; extern int ssl_initialized;
extern int usepw; extern int usepw;

@ -508,7 +508,7 @@ if (debug_scroll > 1) fprintf(stderr, "internal scrollbar: %dx%d\n", w, h);
static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) { static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
int can_input = 0, uid; int can_input = 0, uid = 0;
allowed_input_t input; allowed_input_t input;
ClientData *cd = (ClientData *) client->clientData; ClientData *cd = (ClientData *) client->clientData;
char hint[MAX_BUTTONS * 20]; char hint[MAX_BUTTONS * 20];
@ -523,7 +523,9 @@ static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
can_input = 1; /* XXX distinguish later */ can_input = 1; /* XXX distinguish later */
} }
} }
uid = cd->uid; if (cd) {
uid = cd->uid;
}
if (! can_input) { if (! can_input) {
uid = -uid; uid = -uid;
} }

@ -30,6 +30,9 @@ static int get_latency(void);
static void measure_display_hook(rfbClientPtr cl) { static void measure_display_hook(rfbClientPtr cl) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
return;
}
dtime0(&cd->timer); dtime0(&cd->timer);
} }
@ -50,6 +53,9 @@ static int get_rate(int which) {
while( (cl = rfbClientIteratorNext(iter)) ) { while( (cl = rfbClientIteratorNext(iter)) ) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
if (cl->state != RFB_NORMAL) { if (cl->state != RFB_NORMAL) {
continue; continue;
} }
@ -109,6 +115,9 @@ static int get_latency(void) {
while( (cl = rfbClientIteratorNext(iter)) ) { while( (cl = rfbClientIteratorNext(iter)) ) {
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
if (cl->state != RFB_NORMAL) { if (cl->state != RFB_NORMAL) {
continue; continue;
} }
@ -335,6 +344,9 @@ db = 0;
int got_t2 = 0, got_t3 = 0; int got_t2 = 0, got_t3 = 0;
ClientData *cd = (ClientData *) cl->clientData; ClientData *cd = (ClientData *) cl->clientData;
if (! cd) {
continue;
}
if (cd->send_cmp_rate > 0.0) { if (cd->send_cmp_rate > 0.0) {
continue; continue;
} }

@ -310,6 +310,8 @@ int check_httpdir(void) {
* /path/to/bin/x11vnc * /path/to/bin/x11vnc
* /path/to/bin/../share/x11vnc/classes * /path/to/bin/../share/x11vnc/classes
* 12345678901234567 * 12345678901234567
* /path/to/bin/../share/x11vnc/classes/ssl
* 123456789012345678901
*/ */
if ((q = strrchr(prog, '/')) == NULL) { if ((q = strrchr(prog, '/')) == NULL) {
rfbLog("check_httpdir: bad program path: %s\n", prog); rfbLog("check_httpdir: bad program path: %s\n", prog);
@ -317,10 +319,14 @@ int check_httpdir(void) {
return 0; return 0;
} }
len = strlen(prog) + 17 + 1; len = strlen(prog) + 21 + 1;
*q = '\0'; *q = '\0';
httpdir = (char *) malloc(len); httpdir = (char *) malloc(len);
snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog); if (use_openssl || use_stunnel) {
snprintf(httpdir, len, "%s/../share/x11vnc/classes/ssl", prog);
} else {
snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog);
}
free(prog); free(prog);
if (stat(httpdir, &sbuf) == 0) { if (stat(httpdir, &sbuf) == 0) {
@ -331,16 +337,32 @@ int check_httpdir(void) {
return 1; return 1;
} else { } else {
/* try some hardwires: */ /* try some hardwires: */
if (stat("/usr/local/share/x11vnc/classes", int i;
&sbuf) == 0) { char **use;
http_dir = char *list[] = {
strdup("/usr/local/share/x11vnc/classes"); "/usr/local/share/x11vnc/classes",
return 1; "/usr/share/x11vnc/classes",
NULL
};
char *ssllist[] = {
"/usr/local/share/x11vnc/classes/ssl",
"/usr/share/x11vnc/classes/ssl",
NULL
};
if (use_openssl || use_stunnel) {
use = ssllist;
} else {
use = list;
} }
if (stat("/usr/share/x11vnc/classes", &sbuf) == 0) { i = 0;
http_dir = strdup("/usr/share/x11vnc/classes"); while (use[i] != NULL) {
return 1; if (stat(use[i], &sbuf) == 0) {
http_dir = strdup(use[i]);
return 1;
}
i++;
} }
rfbLog("check_httpdir: bad guess:\n"); rfbLog("check_httpdir: bad guess:\n");
rfbLog(" %s\n", httpdir); rfbLog(" %s\n", httpdir);
return 0; return 0;
@ -354,6 +376,19 @@ void http_connections(int on) {
} }
if (on) { if (on) {
rfbLog("http_connections: turning on http service.\n"); rfbLog("http_connections: turning on http service.\n");
if (inetd && use_openssl) {
/*
* try to work around rapid fire https requests
* in inetd mode... ugh.
*/
if (screen->httpPort == 0) {
int port = find_free_port(5800, 5850);
if (port) {
screen->httpPort = port;
}
}
}
screen->httpInitDone = FALSE; screen->httpInitDone = FALSE;
screen->httpDir = http_dir; screen->httpDir = http_dir;
if (check_httpdir()) { if (check_httpdir()) {
@ -3785,6 +3820,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "aro=%s:%d", p, use_stunnel); snprintf(buf, bufn, "aro=%s:%d", p, use_stunnel);
} else if (!strcmp(p, "stunnel_pem")) { } else if (!strcmp(p, "stunnel_pem")) {
snprintf(buf, bufn, "aro=%s:%s", p, NONUL(stunnel_pem)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(stunnel_pem));
} else if (!strcmp(p, "https")) {
snprintf(buf, bufn, "aro=%s:%d", p, https_port_num);
} else if (!strcmp(p, "usepw")) { } else if (!strcmp(p, "usepw")) {
snprintf(buf, bufn, "aro=%s:%d", p, usepw); snprintf(buf, bufn, "aro=%s:%d", p, usepw);
} else if (!strcmp(p, "using_shm")) { } else if (!strcmp(p, "using_shm")) {

@ -1924,8 +1924,17 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
* at screen creation time. * at screen creation time.
*/ */
/* event callbacks: */
screen->newClientHook = new_client;
screen->kbdAddEvent = keyboard;
screen->ptrAddEvent = pointer;
screen->setXCutText = xcut_receive;
/* called from inetd, we need to treat stdio as our socket */ /* called from inetd, we need to treat stdio as our socket */
if (inetd) { if (inetd && use_openssl) {
/* accept_openssl() called later */
screen->port = 0;
} else if (inetd) {
int fd = dup(0); int fd = dup(0);
if (fd < 0) { if (fd < 0) {
rfbLogEnable(1); rfbLogEnable(1);
@ -1955,16 +1964,13 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen->deferUpdateTime = defer_update; screen->deferUpdateTime = defer_update;
} }
/* event callbacks: */
screen->newClientHook = new_client;
screen->kbdAddEvent = keyboard;
screen->ptrAddEvent = pointer;
screen->setXCutText = xcut_receive;
rfbInitServer(screen); rfbInitServer(screen);
if (use_openssl) { if (use_openssl) {
openssl_port(); openssl_port();
if (https_port_num >= 0) {
https_port();
}
} }
install_passwds(); install_passwds();
@ -1976,9 +1982,9 @@ static void announce(int lport, int ssl, char *iface) {
char *tvdt; char *tvdt;
if (! ssl) { if (! ssl) {
tvdt = "The VNC desktop"; tvdt = "The VNC desktop is: ";
} else { } else {
tvdt = "The SSL VNC desktop"; tvdt = "The SSL VNC desktop is: ";
} }
if (iface != NULL && *iface != '\0' && strcmp(iface, "any")) { if (iface != NULL && *iface != '\0' && strcmp(iface, "any")) {
@ -1993,18 +1999,18 @@ static void announce(int lport, int ssl, char *iface) {
if (lport >= 5900) { if (lport >= 5900) {
snprintf(vnc_desktop_name, sz, "%s:%d", snprintf(vnc_desktop_name, sz, "%s:%d",
host, lport - 5900); host, lport - 5900);
fprintf(stderr, "%s is %s\n", tvdt, fprintf(stderr, "%s %s\n", tvdt,
vnc_desktop_name); vnc_desktop_name);
} else { } else {
snprintf(vnc_desktop_name, sz, "%s:%d", snprintf(vnc_desktop_name, sz, "%s:%d",
host, lport); host, lport);
fprintf(stderr, "%s is %s\n", tvdt, fprintf(stderr, "%s %s\n", tvdt,
vnc_desktop_name); vnc_desktop_name);
} }
} else if (lport >= 5900) { } else if (lport >= 5900) {
snprintf(vnc_desktop_name, sz, "%s:%d", snprintf(vnc_desktop_name, sz, "%s:%d",
host, lport - 5900); host, lport - 5900);
fprintf(stderr, "%s is %s\n", tvdt, vnc_desktop_name); fprintf(stderr, "%s %s\n", tvdt, vnc_desktop_name);
if (lport >= 6000) { if (lport >= 6000) {
rfbLog("possible aliases: %s:%d, " rfbLog("possible aliases: %s:%d, "
"%s::%d\n", host, lport, "%s::%d\n", host, lport,
@ -2013,17 +2019,41 @@ static void announce(int lport, int ssl, char *iface) {
} else { } else {
snprintf(vnc_desktop_name, sz, "%s:%d", snprintf(vnc_desktop_name, sz, "%s:%d",
host, lport); host, lport);
fprintf(stderr, "%s is %s\n", tvdt, vnc_desktop_name); fprintf(stderr, "%s %s\n", tvdt, vnc_desktop_name);
rfbLog("possible alias: %s::%d\n", rfbLog("possible alias: %s::%d\n",
host, lport); host, lport);
} }
} }
} }
static void announce_http(int lport, int ssl, char *iface) {
char *host = this_host();
char *jvu;
if (ssl == 1) {
jvu = "Java SSL viewer URL: https";
} else if (ssl == 2) {
jvu = "Java SSL viewer URL: http";
} else {
jvu = "Java viewer URL: http";
}
if (iface != NULL && *iface != '\0' && strcmp(iface, "any")) {
host = iface;
}
if (host != NULL) {
if (! inetd) {
fprintf(stderr, "%s://%s:%d/\n", jvu, host, lport);
}
}
}
void set_vnc_desktop_name(void) { void set_vnc_desktop_name(void) {
sprintf(vnc_desktop_name, "unknown"); sprintf(vnc_desktop_name, "unknown");
if (inetd) { if (inetd) {
sprintf(vnc_desktop_name, "inetd-no-further-clients"); sprintf(vnc_desktop_name, "%s/inetd-no-further-clients",
this_host());
} }
if (screen->port) { if (screen->port) {
@ -2031,10 +2061,28 @@ void set_vnc_desktop_name(void) {
rfbLog("\n"); rfbLog("\n");
} }
announce(screen->port, 0, listen_str); if (use_openssl) {
announce(screen->port, 1, listen_str);
} else {
announce(screen->port, 0, listen_str);
}
if (stunnel_port) { if (stunnel_port) {
announce(stunnel_port, 1, NULL); announce(stunnel_port, 1, NULL);
} }
if (screen->httpListenSock > -1 && screen->httpPort) {
if (use_openssl) {
announce_http(screen->port, 1, listen_str);
if (https_port_num >= 0) {
announce_http(https_port_num, 1,
listen_str);
}
announce_http(screen->httpPort, 2, listen_str);
} else if (use_stunnel) {
announce_http(screen->httpPort, 2, listen_str);
} else {
announce_http(screen->httpPort, 0, listen_str);
}
}
fflush(stderr); fflush(stderr);
if (inetd) { if (inetd) {
@ -2043,6 +2091,8 @@ void set_vnc_desktop_name(void) {
fprintf(stdout, "PORT=%d\n", screen->port); fprintf(stdout, "PORT=%d\n", screen->port);
if (stunnel_port) { if (stunnel_port) {
fprintf(stdout, "SSLPORT=%d\n", stunnel_port); fprintf(stdout, "SSLPORT=%d\n", stunnel_port);
} else if (use_openssl) {
fprintf(stdout, "SSLPORT=%d\n", screen->port);
} }
fflush(stdout); fflush(stdout);
if (flagfile) { if (flagfile) {

@ -29,6 +29,8 @@ void check_stunnel(void) {
} }
last_check = now; last_check = now;
/* double check that stunnel is still running: */
if (stunnel_pid > 0) { if (stunnel_pid > 0) {
int status; int status;
waitpid(stunnel_pid, &status, WNOHANG); waitpid(stunnel_pid, &status, WNOHANG);

File diff suppressed because it is too large Load Diff

@ -4,14 +4,23 @@
/* -- sslhelper.h -- */ /* -- sslhelper.h -- */
#define OPENSSL_INETD 1
#define OPENSSL_VNC 2
#define OPENSSL_HTTPS 3
extern int openssl_sock; extern int openssl_sock;
extern int openssl_port_num;
extern int https_sock;
extern pid_t openssl_last_helper_pid; extern pid_t openssl_last_helper_pid;
extern int openssl_present(void); extern int openssl_present(void);
extern void openssl_init(void); extern void openssl_init(void);
extern void openssl_port(void); extern void openssl_port(void);
extern void https_port(void);
extern void check_openssl(void); extern void check_openssl(void);
extern void ssh_helper_pid(pid_t pid, int sock); extern void check_https(void);
extern void ssl_helper_pid(pid_t pid, int sock);
extern void accept_openssl(int mode);
#endif /* _X11VNC_SSLHELPER_H */ #endif /* _X11VNC_SSLHELPER_H */

@ -295,6 +295,7 @@ Permissions
stunnel stunnel
=F stunnel_pem: =F stunnel_pem:
=F sslverify: =F sslverify:
https:
=GAL LOFF =GAL LOFF
=GAL Misc-Perms:: =GAL Misc-Perms::
safer safer

@ -306,6 +306,7 @@ char gui_code[] = "";
" stunnel\n" " stunnel\n"
" =F stunnel_pem:\n" " =F stunnel_pem:\n"
" =F sslverify:\n" " =F sslverify:\n"
" https:\n"
" =GAL LOFF\n" " =GAL LOFF\n"
" =GAL Misc-Perms::\n" " =GAL Misc-Perms::\n"
" safer\n" " safer\n"

@ -109,9 +109,16 @@ void unixpw_screen(int init) {
zero_fb(0, 0, dpy_x, dpy_y); zero_fb(0, 0, dpy_x, dpy_y);
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
x = nfix(dpy_x / 2 - strlen(log) * char_w, dpy_x); x = nfix(dpy_x / 2 - strlen(log) * char_w, dpy_x);
y = dpy_y / 4; y = dpy_y / 4;
if (scaling) {
x = (int) (x * scale_fac);
y = (int) (y * scale_fac);
}
rfbDrawString(screen, &default8x16Font, x, y, log, white()); rfbDrawString(screen, &default8x16Font, x, y, log, white());
char_x = x; char_x = x;
@ -120,7 +127,11 @@ void unixpw_screen(int init) {
char_row = 0; char_row = 0;
} }
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); if (scaling) {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 1);
} else {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
}
} }
@ -322,7 +333,7 @@ int crypt_verify(char *user, char *pass) {
if (pass[n-1] == '\n') { if (pass[n-1] == '\n') {
pass[n-1] = '\0'; pass[n-1] = '\0';
} }
cr = crypt(pass, realpw); cr = (char *) crypt(pass, realpw);
if (cr == NULL) { if (cr == NULL) {
return 0; return 0;
} }
@ -741,7 +752,11 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
char_col = strlen(log); char_col = strlen(log);
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); if (scaling) {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 1);
} else {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
}
unixpw_last_try_time = time(0); unixpw_last_try_time = time(0);
unixpw_keystroke(0, 0, 2); unixpw_keystroke(0, 0, 2);
@ -805,9 +820,20 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
user[u_cnt-1] = '\0'; user[u_cnt-1] = '\0';
x = text_x(); x = text_x();
y = text_y(); y = text_y();
zero_fb(x - char_w, y - char_h, x, y); if (scaling) {
mark_rect_as_modified(x - char_w, y - char_h, int x2 = x / scale_fac;
x, y, 0); int y2 = y / scale_fac;
int w2 = char_w / scale_fac;
int h2 = char_h / scale_fac;
zero_fb(x2 - w2, y2 - h2, x2, y2);
mark_rect_as_modified(x2 - w2,
y2 - h2, x2, y2, 0);
} else {
zero_fb(x - char_w, y - char_h, x, y);
mark_rect_as_modified(x - char_w,
y - char_h, x, y, 0);
}
char_col--; char_col--;
u_cnt--; u_cnt--;
} }
@ -836,7 +862,11 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
white()); white());
char_col = strlen(pw); char_col = strlen(pw);
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); if (scaling) {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 1);
} else {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
}
return; return;
} }
if (keysym <= ' ' || keysym >= 0x7f) { if (keysym <= ' ' || keysym >= 0x7f) {
@ -862,7 +892,11 @@ if (db && db <= 2) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x %s\n", u_cnt, x, y
keystr[1] = '\0'; keystr[1] = '\0';
rfbDrawString(screen, &default8x16Font, x, y, keystr, white()); rfbDrawString(screen, &default8x16Font, x, y, keystr, white());
mark_rect_as_modified(x, y-char_h, x+char_w, y, 0); if (scaling) {
mark_rect_as_modified(x, y-char_h, x+char_w, y, 1);
} else {
mark_rect_as_modified(x, y-char_h, x+char_w, y, 0);
}
char_col++; char_col++;
} else if (in_passwd) { } else if (in_passwd) {
@ -920,6 +954,10 @@ static void apply_opts (char *user) {
ClientData *cd = (ClientData *) unixpw_client->clientData; ClientData *cd = (ClientData *) unixpw_client->clientData;
rfbClientPtr cl = unixpw_client; rfbClientPtr cl = unixpw_client;
int i; int i;
if (! cd) {
return;
}
if (user) { if (user) {
if (cd->unixname) { if (cd->unixname) {
@ -1000,7 +1038,11 @@ void unixpw_deny(void) {
y = char_y + char_row * char_h; y = char_y + char_row * char_h;
rfbDrawString(screen, &default8x16Font, x, y, pd, white()); rfbDrawString(screen, &default8x16Font, x, y, pd, white());
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); if (scaling) {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 1);
} else {
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
}
for (i=0; i<5; i++) { for (i=0; i<5; i++) {
rfbPE(-1); rfbPE(-1);

@ -2,7 +2,7 @@
.TH X11VNC "1" "March 2006" "x11vnc " "User Commands" .TH X11VNC "1" "March 2006" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.8.1, lastmod: 2006-03-11 version: 0.8.1, lastmod: 2006-03-27
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -519,22 +519,24 @@ are view-only during this period.
.IP .IP
Since the detailed behavior of Since the detailed behavior of
.IR su (1) .IR su (1)
can vary from OS can vary from
to OS and for local configurations, please test the mode OS to OS and for local configurations, test the mode
carefully on your systems before using it in production. carefully on your systems before using it in production.
E.g. try different combinations of valid/invalid Test different combinations of valid/invalid usernames
usernames and valid/invalid passwords to see if it and valid/invalid passwords to see if it behaves as
behaves correctly. x11vnc will be conservative and expected. x11vnc will attempt to be conservative and
reject a user if anything abnormal occurs. reject a login if anything abnormal occurs.
.IP .IP
For example, on FreeBSD and the other BSD's by default On FreeBSD and the other BSD's by default it is
it is impossible for the user running x11vnc to validate impossible for the user running x11vnc to validate
his *own* password via his *own* password via
.IR su (1) .IR su (1)
(evidently commenting (evidently commenting out
out the pam_self.so entry in /etc/pam.d/su eliminates the pam_self.so entry in /etc/pam.d/su eliminates this
the problem). So the x11vnc login will always fail for problem). So the x11vnc login will always *fail* for
this case. A possible workaround would be to start this case (even when the correct password is supplied).
.IP
A possible workaround for this would be to start
x11vnc as root with the "\fB-users\fR \fI+nobody\fR" option to x11vnc as root with the "\fB-users\fR \fI+nobody\fR" option to
immediately switch to user nobody. Another source of immediately switch to user nobody. Another source of
problems are PAM modules that prompt for extra info, problems are PAM modules that prompt for extra info,
@ -557,54 +559,56 @@ to come from the same machine x11vnc is running on
\fB-stunnel\fR SSL mode be used for encryption over the \fB-stunnel\fR SSL mode be used for encryption over the
network.(see the description of \fB-stunnel\fR below). network.(see the description of \fB-stunnel\fR below).
.IP .IP
As a convenience, if you Note: as a convenience, if you
.IR ssh (1) .IR ssh (1)
in and start x11vnc it in and start
will check if the environment variable SSH_CONNECTION x11vnc it will check if the environment variable
is set and appears reasonable. If it does, then the SSH_CONNECTION is set and appears reasonable. If it
\fB-ssl\fR or \fB-stunnel\fR requirement will be dropped since it is does, then the \fB-ssl\fR or \fB-stunnel\fR requirement will be
assumed you are using ssh for the encrypted tunnelling. dropped since it is assumed you are using ssh for the
\fB-localhost\fR is still enforced. Use \fB-ssl\fR or \fB-stunnel\fR to encrypted tunnelling. \fB-localhost\fR is still enforced.
force SSL usage for this case. Use \fB-ssl\fR or \fB-stunnel\fR to force SSL usage even if
.IP SSH_CONNECTION is set.
To override these restrictions you can set environment .IP
variables before starting x11vnc: To override the above restrictions you can set
environment variables before starting x11vnc:
.IP .IP
Set UNIXPW_DISABLE_SSL=1 to disable requiring either Set UNIXPW_DISABLE_SSL=1 to disable requiring either
\fB-ssl\fR or \fB-stunnel.\fR Evidently you will be using a \fB-ssl\fR or \fB-stunnel.\fR Evidently you will be using a
different method to encrypt the data between the different method to encrypt the data between the
vncviewer and x11vnc: e.g. vncviewer and x11vnc: perhaps
.IR ssh (1) .IR ssh (1)
or a VPN. Note that or an IPSEC VPN.
use of \fB-localhost\fR with .IP
Note that use of \fB-localhost\fR with
.IR ssh (1) .IR ssh (1)
is roughly the same as is roughly
requiring a Unix user login (since a Unix password or the same as requiring a Unix user login (since a Unix
the user's public key authentication is used by sshd on password or the user's public key authentication is
the machine where x11vnc runs and only local connections used by sshd on the machine where x11vnc runs and only
are accepted) local connections from that machine are accepted)
.IP .IP
Set UNIXPW_DISABLE_LOCALHOST=1 to disable the \fB-localhost\fR Set UNIXPW_DISABLE_LOCALHOST=1 to disable the \fB-localhost\fR
requirement in Method 2). One should never do this requirement in Method 2). One should never do this
(i.e. allow the Unix passwords to be sniffed on the (i.e. allow the Unix passwords to be sniffed on the
network). network).
.IP .IP
Regarding reverse connections (e.g. \fB-R\fR connect:host), Regarding reverse connections (e.g. \fB-R\fR connect:host
if the \fB-localhost\fR constraint is in effect then reverse and \fB-connect\fR host), when the \fB-localhost\fR constraint is
connections can only be used to connect to the same in effect then reverse connections can only be used
machine x11vnc is running on (default port 5500). to connect to the same machine x11vnc is running on
Please use a ssh or stunnel port redirection to the (default port 5500). Please use a ssh or stunnel port
viewer machine to tunnel the reverse connection over redirection to the viewer machine to tunnel the reverse
an encrypted channel. Note that in \fB-ssl\fR mode reverse connection over an encrypted channel. Note that in \fB-ssl\fR
connection are disabled. mode reverse connection are disabled (see below).
.IP .IP
XXX \fB-inetd\fR + \fB-ssl\fR In \fB-inetd\fR mode the Method 1) will be enforced (not
In \fB-inetd\fR mode the two settings are attempted to be Method 2). With \fB-ssl\fR in effect reverse connections
enforced for reverse connections. Be sure to also are disabled. If you override this via env. var, be
use encryption from the viewer to inetd since x11vnc sure to also use encryption from the viewer to inetd.
cannot guess easily if it is encrpyted. Tip: you can Tip: you can also have your own stunnel spawn x11vnc
also have your own stunnel spawn x11vnc in \fB-inetd\fR mode in \fB-inetd\fR mode (thereby bypassing inetd). See the FAQ
(i.e. bypassing inetd). See the FAQ for details. for details.
.IP .IP
The user names in the comma separated [list] can have The user names in the comma separated [list] can have
per-user options after a ":", e.g. "fred:opts" per-user options after a ":", e.g. "fred:opts"
@ -619,9 +623,9 @@ are allowed to log in after supplying a valid password.
Use "deny" to explicitly deny some users if you use Use "deny" to explicitly deny some users if you use
"*" to set a global option. "*" to set a global option.
.IP .IP
There are also some tools for testing password if [list] There are also some utilities for testing password
starts with the "%" character. See the quick_pw() if [list] starts with the "%" character. See the
function for details. quick_pw() function in the source for details.
.PP .PP
\fB-unixpw_nis\fR \fI[list]\fR \fB-unixpw_nis\fR \fI[list]\fR
.IP .IP
@ -632,19 +636,21 @@ use the traditional
.IR getpwnam (3) .IR getpwnam (3)
+ +
.IR crypt (3) .IR crypt (3)
method method to
instead. This requires that the encrpyted passwords verify passwords instead. This requires that the
be readable. Passwords stored in /etc/shadow will encrpyted passwords be readable. Passwords stored
be inaccessible unless run as root. This is called in /etc/shadow will be inaccessible unless x11vnc
"NIS" mode simply because in most NIS setups the is run as root.
user encrypted passwords are accessible (e.g. "ypcat .IP
passwd"). NIS is not required for this mode to work This is called "NIS" mode simply because in most
(only that NIS setups the user encrypted passwords are accessible
(e.g. "ypcat passwd"). NIS is not required for this
mode to work (only that
.IR getpwnam (3) .IR getpwnam (3)
return the encrpyted password return the encrpyted
is required), but it is unlikely it will work for any password is required), but it is unlikely it will work
other environment. All of the \fB-unixpw\fR options and for any other modern environment. All of the \fB-unixpw\fR
contraints apply. options and contraints apply.
.PP .PP
\fB-ssl\fR \fI[pem]\fR \fB-ssl\fR \fI[pem]\fR
.IP .IP
@ -655,25 +661,28 @@ into x11vnc at build time. If x11vnc is not built
with libssl support it will exit immediately when \fB-ssl\fR with libssl support it will exit immediately when \fB-ssl\fR
is prescribed. is prescribed.
.IP .IP
[pem] is optional, use "\fB-ssl\fR \fI/path/to/mycert.pem\fR" to [pem] is optional, use "\fB-ssl\fR \fI/path/to/mycert.pem\fR"
specify a PEM certificate file to use to identify and to specify a PEM certificate file to use to identify
provide a key for this server. and provide a key for this server. See
.IP .IR openssl (1)
Connecting VNC viewer SSL tunnels can authenticate for what a PEM can be.
this server if they have the public key part of the .IP
certificate (or a common certificate authority, CA, Connecting VNC viewer SSL tunnels can optionally
verifies this server's cert). This is used to prevent authenticate this server if they have the public
man-in-the-middle attacks. Otherwise, if the VNC viewer key part of the certificate (or a common certificate
accepts this server's key without verification, at authority, CA, is a more sophisicated way to verify
least the traffic is protected from passive sniffing this server's cert). This is used to prevent
on the network. man-in-the-middle attacks. Otherwise, if the VNC
viewer accepts this server's key without verification,
at least the traffic is protected from passive sniffing
on the network (but NOT from man-in-the-middle attacks).
.IP .IP
If [pem] is not supplied and the If [pem] is not supplied and the
.IR openssl (1) .IR openssl (1)
utility utility
command exists in PATH, then a temporary, self-signed command exists in PATH, then a temporary, self-signed
certificate will be generated for this session (this certificate will be generated for this session (this
may take 5-20 seconds on slow machines). If may take 5-30 seconds on slow machines). If
.IR openssl (1) .IR openssl (1)
cannot be used to generate a temporary certificate cannot be used to generate a temporary certificate
x11vnc exits immediately. x11vnc exits immediately.
@ -681,9 +690,10 @@ x11vnc exits immediately.
If successful in using If successful in using
.IR openssl (1) .IR openssl (1)
to generate a to generate a
certificate, the public part of it will be displayed temporary certificate, the public part of it will be
to stdout (e.g. one could copy it to the client-side displayed to stderr (e.g. one could copy it to the
to provide authentication of the server to VNC viewers.) client-side to provide authentication of the server to
VNC viewers.)
.IP .IP
Set the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc Set the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc
print out the entire certificate, including the PRIVATE print out the entire certificate, including the PRIVATE
@ -693,22 +703,25 @@ to not delete the temporary PEM file: the file name
will be printed to stderr (so one could move it to a will be printed to stderr (so one could move it to a
safe place for reuse). safe place for reuse).
.IP .IP
Reverse connections are disabled in \fB-ssl\fR Reverse connections are disabled in \fB-ssl\fR mode because
mode because the data cannot be encrypted. there is no way to ensure that data channel will
Set X11VNC_SSL_ALLOW_REVERSE=1 to override this. be encrypted. Set X11VNC_SSL_ALLOW_REVERSE=1 to
override this.
.IP .IP
Your VNC viewer will also need to be able to connect Your VNC viewer will also need to be able to connect
via SSL. See the discussion below under \fB-stunnel\fR and via SSL. See the discussion below under \fB-stunnel\fR
the FAQ for how this might be achieved. E.g. on Unix it and the FAQ for how this might be achieved. E.g. on
is easy to write a shell script that starts up stunnel Unix it is easy to write a shell script that starts up
and then vncviewer. stunnel and then vncviewer. Also in the x11vnc source
a SSL enabled Java VNC Viewer applet is provided in
the classes/ssl directory.
.PP .PP
\fB-sslverify\fR \fI[path]\fR \fB-sslverify\fR \fI[path]\fR
.IP .IP
For either of the \fB-ssl\fR or \fB-stunnel\fR modes, use [path] For either of the \fB-ssl\fR or \fB-stunnel\fR modes, use [path]
to provide certificates to authenticate incoming VNC to provide certificates to authenticate incoming VNC
client connections. This can be used as a method to client connections. This can be used as a method to
replace standard password authentication. replace standard password authentication of clients.
.IP .IP
If [path] is a directory it contains the client (or CA) If [path] is a directory it contains the client (or CA)
certificates in separate files. If [path] is a file, it certificates in separate files. If [path] is a file, it
@ -721,7 +734,7 @@ manpage for details.
To create certificates for all sorts of authentications To create certificates for all sorts of authentications
(clients, servers, via CA, etc) see the (clients, servers, via CA, etc) see the
.IR openssl (1) .IR openssl (1)
command. Of particular usefulness is the x509 command. Of particular usefulness is the "x509"
subcommand of subcommand of
.IR openssl (1). .IR openssl (1).
.PP .PP
@ -729,34 +742,41 @@ subcommand of
.IP .IP
Use the Use the
.IR stunnel (8) .IR stunnel (8)
(www.stunnel.org) to provide (www.stunnel.org) to provide an
an encrypted SSL tunnel between viewers and x11vnc. encrypted SSL tunnel between viewers and x11vnc. This
This requires stunnel to be installed on the system and was implemented prior to the integrated \fB-ssl\fR encrpytion.
available via PATH (n.b. stunnel is often installed in It works well. This requires stunnel to be installed
sbin directories). Version 4.x of stunnel is assumed on the system and available via PATH (n.b. stunnel is
(but see \fB-stunnel3\fR below.) often installed in sbin directories). Version 4.x of
stunnel is assumed (but see \fB-stunnel3\fR below.)
.IP .IP
[pem] is optional, use "\fB-stunnel\fR \fI/path/to/stunnel.pem\fR" [pem] is optional, use "\fB-stunnel\fR \fI/path/to/stunnel.pem\fR"
to specify a PEM certificate file to pass to stunnel. to specify a PEM certificate file to pass to stunnel.
Whether one is needed or not depends on your stunnel Whether one is needed or not depends on your stunnel
configuration. stunnel often generates one at install configuration. stunnel often generates one at install
time. time. See the stunnel documentation for details.
.IP .IP
stunnel is started up as a child process of x11vnc and stunnel is started up as a child process of x11vnc and
any SSL connections stunnel receives are decrypted and any SSL connections stunnel receives are decrypted and
sent to x11vnc over a local socket. The strings sent to x11vnc over a local socket. The strings
"The SSL VNC desktop is ..." and "SSLPORT=..." "The SSL VNC desktop is ..." and "SSLPORT=..."
are printed out at startup. are printed out at startup to indicate this.
.IP .IP
The \fB-localhost\fR option is enforced by default to The \fB-localhost\fR option is enforced by default
avoid people routing around the SSL channel. Set to avoid people routing around the SSL channel.
STUNNEL_DISABLE_LOCALHOST=1 to disable the requirement. Set STUNNEL_DISABLE_LOCALHOST=1 before starting x11vnc
to disable the requirement.
.IP .IP
Your VNC viewer will also need to be able to connect Your VNC viewer will also need to be able to connect via
via SSL. Unfortunately not too many do this. UltraVNC SSL. Unfortunately not too many do this. UltraVNC has
seems to have an encryption plugin. It is not too an encryption plugin but it does not seem to be SSL.
difficult to set up an stunnel or other SSL tunnel on .IP
the viewer side. In the x11vnc distribution, a patched TightVNC Java
applet is provided in classes/ssl that does SSL
connections (only).
.IP
It is also not too difficult to set up an stunnel or
other SSL tunnel on the viewer side.
.IP .IP
A simple example on Unix using stunnel 3.x is: A simple example on Unix using stunnel 3.x is:
.IP .IP
@ -772,6 +792,37 @@ for more examples.
Use version 3.x stunnel command line syntax instead of Use version 3.x stunnel command line syntax instead of
version 4.x version 4.x
.PP .PP
\fB-https\fR \fI[port]\fR
.IP
Choose a separate HTTPS port (-ssl mode only).
.IP
In \fB-ssl\fR mode, it turns out you can use the
single VNC port (e.g. 5900) for both VNC and HTTPS
connections. (HTTPS is used to retrieve a SSL-aware
VncViewer.jar applet that is provided with x11vnc).
Since both use SSL the implementation was extended to
detect if HTTP traffic (i.e. GET) is taking place and
handle it accordingly. The URL would be, e.g.:
.IP
https://mymachine.org:5900/
.IP
This is convenient for firewalls, etc, because only one
port needs to be allowed in. However, this heuristic
adds a few seconds delay to each connection and can be
unreliable (especially if the user takes much time to
ponder the Certificate dialogs in his browser, Java VM,
or VNC Viewer applet. That's right 3 separate "Are
you sure you want to connect" dialogs!)
.IP
So use the \fB-https\fR option to provide a separate, more
reliable HTTPS port that x11vnc will listen on. If
[port] is not provided (or is 0), one is autoselected.
The URL to use is printed out at startup.
.IP
The SSL Java applet directory is specified via the
\fB-httpdir\fR option. If not supplied it will try to guess
the directory as though the \fB-http\fR option was supplied.
.PP
\fB-usepw\fR \fB-usepw\fR
.IP .IP
If no other password method was supplied on the command If no other password method was supplied on the command
@ -1030,9 +1081,13 @@ to go into a blacked out region.
\fB-xinerama\fR \fB-xinerama\fR
.IP .IP
If your screen is composed of multiple monitors If your screen is composed of multiple monitors
.PP
\fB-noxinerama\fR
.IP
glued together via XINERAMA, and that screen is glued together via XINERAMA, and that screen is
not a rectangle this option will try to guess the not a rectangle this option will try to guess the
areas to black out (if your system has libXinerama). areas to black out (if your system has libXinerama).
default: \fB-xinerama\fR
.IP .IP
In general, we have noticed on XINERAMA displays you In general, we have noticed on XINERAMA displays you
may need to use the "\fB-xwarppointer\fR" option if the mouse may need to use the "\fB-xwarppointer\fR" option if the mouse
@ -2898,9 +2953,9 @@ aro= noop display vncdisplay desktopname guess_desktop
http_url auth xauth users rootshift clipshift http_url auth xauth users rootshift clipshift
scale_str scaled_x scaled_y scale_numer scale_denom scale_str scaled_x scaled_y scale_numer scale_denom
scale_fac scaling_blend scaling_nomult4 scaling_pad scale_fac scaling_blend scaling_nomult4 scaling_pad
scaling_interpolate inetd privremote unsafe safer scaling_interpolate inetd privremote unsafe safer nocmds
nocmds passwdfile unixpw unixpw_nis unixpw_list ssl passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem
ssl_pem sslverify stunnel stunnel_pem usepw using_shm sslverify stunnel stunnel_pem https usepw using_shm
logfile o flag rc norc h help V version lastmod bg logfile o flag rc norc h help V version lastmod bg
sigpipe threads readrate netrate netlatency pipeinput sigpipe threads readrate netrate netlatency pipeinput
clients client_count pid ext_xtest ext_xtrap ext_xrecord clients client_count pid ext_xtest ext_xtrap ext_xrecord

@ -473,6 +473,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
check_gui_inputs(); check_gui_inputs();
check_stunnel(); check_stunnel();
check_openssl(); check_openssl();
check_https();
record_last_fb_update(); record_last_fb_update();
check_padded_fb(); check_padded_fb();
check_fixscreen(); check_fixscreen();
@ -1617,6 +1618,16 @@ int main(int argc, char* argv[]) {
i++; i++;
} }
} }
} else if (!strcmp(arg, "-https")) {
https_port_num = 0;
try_http = 1;
if (i < argc-1) {
char *s = argv[i+1];
if (s[0] != '-') {
https_port_num = atoi(s);
i++;
}
}
} else if (!strcmp(arg, "-nopw")) { } else if (!strcmp(arg, "-nopw")) {
nopw = 1; nopw = 1;
} else if (!strcmp(arg, "-usepw")) { } else if (!strcmp(arg, "-usepw")) {
@ -2403,7 +2414,10 @@ int main(int argc, char* argv[]) {
launch_gui = 0; launch_gui = 0;
} }
if (! inetd && unixpw) { if (unixpw) {
if (inetd) {
use_stunnel = 0;
}
if (! use_stunnel && ! use_openssl) { if (! use_stunnel && ! use_openssl) {
if (have_ssh_env()) { if (have_ssh_env()) {
char *s = getenv("SSH_CONNECTION"); char *s = getenv("SSH_CONNECTION");
@ -2426,6 +2440,9 @@ int main(int argc, char* argv[]) {
if (openssl_present()) { if (openssl_present()) {
rfbLog("set -ssl in -unixpw mode.\n"); rfbLog("set -ssl in -unixpw mode.\n");
use_openssl = 1; use_openssl = 1;
} else if (inetd) {
rfbLog("could not set -ssl in -inetd + -unixpw mode.\n");
exit(1);
} else { } else {
rfbLog("set -stunnel in -unixpw mode.\n"); rfbLog("set -stunnel in -unixpw mode.\n");
use_stunnel = 1; use_stunnel = 1;
@ -2447,6 +2464,10 @@ int main(int argc, char* argv[]) {
rfbLog("-sslverify must be used with -ssl or -stunnel\n"); rfbLog("-sslverify must be used with -ssl or -stunnel\n");
exit(1); exit(1);
} }
if (https_port_num >= 0 && ! use_openssl) {
rfbLog("-https must be used with -ssl\n");
exit(1);
}
/* fixup settings that do not make sense */ /* fixup settings that do not make sense */
@ -2498,7 +2519,9 @@ int main(int argc, char* argv[]) {
shared = 0; shared = 0;
connect_once = 1; connect_once = 1;
bg = 0; bg = 0;
use_stunnel = 0; if (use_stunnel) {
exit(1);
}
/* others? */ /* others? */
} }
@ -3065,6 +3088,9 @@ int main(int argc, char* argv[]) {
initialize_allowed_input(); initialize_allowed_input();
if (inetd && use_openssl) {
accept_openssl(OPENSSL_INETD);
}
if (! inetd && ! use_openssl) { if (! inetd && ! use_openssl) {
if (! screen->port || screen->listenSock < 0) { if (! screen->port || screen->listenSock < 0) {
rfbLogEnable(1); rfbLogEnable(1);

@ -46,6 +46,7 @@
* -DVNCSHARED to have the vnc display shared by default. * -DVNCSHARED to have the vnc display shared by default.
* -DFOREVER to have -forever on by default. * -DFOREVER to have -forever on by default.
* -DNOREPEAT=0 to have -repeat on by default. * -DNOREPEAT=0 to have -repeat on by default.
* -DXINERAMA=0 to have -noxinerama on by default.
* -DADDKEYSYMS=0 to have -noadd_keysyms the default. * -DADDKEYSYMS=0 to have -noadd_keysyms the default.
* *
* -DREMOTE_DEFAULT=0 to disable remote-control on by default (-yesremote). * -DREMOTE_DEFAULT=0 to disable remote-control on by default (-yesremote).
@ -93,6 +94,10 @@
#define REMOTE_CONTROL 1 #define REMOTE_CONTROL 1
#endif #endif
#ifndef XINERAMA
#define XINERAMA 1
#endif
#ifndef NOPW #ifndef NOPW
#define NOPW 0 #define NOPW 0
#endif #endif
@ -465,7 +470,7 @@ typedef struct _ClientData {
int login_viewonly; int login_viewonly;
time_t login_time; time_t login_time;
pid_t ssh_helper_pid; pid_t ssl_helper_pid;
int had_cursor_shape_updates; int had_cursor_shape_updates;
int had_cursor_pos_updates; int had_cursor_pos_updates;

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.1 lastmod: 2006-03-11"; char lastmod[] = "0.8.1 lastmod: 2006-03-27";
/* X display info */ /* X display info */

@ -680,8 +680,10 @@ void disable_grabserver(Display *in_dpy, int change) {
} }
} }
if (! ok && ! didmsg) { if (! ok && ! didmsg) {
rfbLog("No XTEST or DEC-XTRAP protection from XGrabServer.\n"); rfbLog("*********************************************************\n");
rfbLog("Deadlock if your window manager calls XGrabServer!!\n"); rfbLog("* No XTEST or DEC-XTRAP protection from XGrabServer !!! *\n");
rfbLog("* DEADLOCK if your window manager calls XGrabServer !!! *\n");
rfbLog("*********************************************************\n");
} }
XFlush(in_dpy); XFlush(in_dpy);
} }

Loading…
Cancel
Save