Commit 61383c50 authored by runge's avatar runge

classes/ssl: java viewer now handles auth-basic proxy logins.

misc/enhanced_tightvnc_viewer: update ssvnc.
parent d11b2abd
......@@ -46,8 +46,8 @@
# -showcert Only fetch the certificate using the 'openssl s_client'
# command (openssl(1) must in installed).
#
# See http://www.karlrunge.com/x11vnc/#faq-ssl-ca for details on SSL
# certificates with VNC.
# See http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca for details on
# SSL certificates with VNC.
#
# A few other args (not related to SSL and certs):
#
......@@ -115,6 +115,15 @@
#
VNCIPCMD=${VNCVIEWERCMD:-vncip}
VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
if [ "X$SSVNC_TURBOVNC" != "X" ]; then
if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then
:
else
if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then
VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc"
fi
fi
fi
#
# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc.
#
......@@ -268,6 +277,12 @@ do
;;
"-onelisten") SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
;;
"-sendclipboard") VNCVIEWER_SEND_CLIPBOARD=1; export VNCVIEWER_SEND_CLIPBOARD
;;
"-sendalways") VNCVIEWER_SEND_ALWAYS=1; export VNCVIEWER_SEND_ALWAYS
;;
"-recvtext") shift; VNCVIEWER_RECV_TEXT="$1"; export VNCVIEWER_RECV_TEXT
;;
"-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE
;;
"-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS
......@@ -751,6 +766,19 @@ if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) {
$handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE};
}
my $have_gettimeofday = 0;
eval "use Time::HiRes";
if ($@ eq "") {
$have_gettimeofday = 1;
}
sub gettime {
my $t = "0.0";
if ($have_gettimeofday) {
$t = Time::HiRes::gettimeofday();
}
return $t;
}
sub append_handshake {
my $str = shift;
if ($handshake_file) {
......@@ -1324,12 +1352,19 @@ sub vencrypt_dialog {
} elsif ($minor == 7) {
$viewer_rfb = "RFB 003.007\n";
}
syswrite($sock, $viewer_rfb, 12);
append_handshake("viewer=$viewer_rfb");
my $nsec;
my $t1 = gettime();
my $t0 = gettime();
syswrite($sock, $viewer_rfb, 12);
sysread($sock, $nsec, 1);
$t1 = gettime();
$t1 = sprintf("%.6f", $t1 - $t0);
append_handshake("viewer=$viewer_rfb");
append_handshake("latency=$t1\n");
vdie if $nsec eq "";
$nsec = unpack("C", $nsec);
......
......@@ -73,8 +73,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/RfbProto.java vnc_javasrc/RfbProto
serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
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 2008-04-15 12:54:51.000000000 -0400
@@ -0,0 +1,1456 @@
+++ vnc_javasrc/SSLSocketToMe.java 2009-06-18 09:47:22.000000000 -0400
@@ -0,0 +1,1717 @@
+/*
+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
+ *
......@@ -130,6 +130,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ public DataInputStream is = null;
+ public OutputStream os = null;
+
+ String proxy_auth_string = null;
+ String proxy_dialog_host = null;
+ int proxy_dialog_port = 0;
+
......@@ -648,9 +649,9 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ user_wants_to_see_cert = false;
+ } else {
+ bcd = new BrowserCertsDialog(serv, host + ":" + port);
+ dbg("bcd START");
+ dbg("browser certs dialog START");
+ bcd.queryUser();
+ dbg("bcd DONE");
+ dbg("browser certs dialog DONE");
+ if (bcd.showCertDialog) {
+ String msg = "user wants to see cert";
+ dbg(msg);
......@@ -658,14 +659,17 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new SSLHandshakeException(msg);
+ } else {
+ user_wants_to_see_cert = false;
+ dbg("bcd: user said yes, accept it");
+ dbg("browser certs dialog: user said yes, accept it");
+ }
+ }
+
+ } catch (SSLHandshakeException eh) {
+ dbg("Could not automatically verify Server.");
+ dbg("msg: " + eh.getMessage());
+ String getoutstr = "GET /index.vnc HTTP/1.0\r\nConnection: close\r\n\r\n";
+
+ OutputStream os = socket.getOutputStream();
+ os.write(getoutstr.getBytes());
+ socket.close();
+ socket = null;
+
......@@ -701,6 +705,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ * close socket now, we will reopen after
+ * dialog if user agrees to use the cert.
+ */
+ os = socket.getOutputStream();
+ os.write(getoutstr.getBytes());
+ socket.close();
+ socket = null;
+
......@@ -722,6 +728,15 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new IOException(ehand2.getMessage());
+ }
+
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ ;
+ }
+ socket = null;
+ }
+
+ /*
+ * Now connect a 3rd time, using the cert
+ * retrieved during connection 2 (that the user
......@@ -806,6 +821,95 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ return n;
+ }
+
+ private void proxy_helper(String proxyHost, int proxyPort) {
+
+ boolean proxy_auth = false;
+ String proxy_auth_basic_realm = "";
+ String hp = host + ":" + port;
+ dbg("proxy_helper: " + proxyHost + ":" + proxyPort + " hp: " + hp);
+
+ for (int k=0; k < 2; k++) {
+ dbg("proxy_in_use psocket:");
+
+ if (proxySock != null) {
+ try {
+ proxySock.close();
+ } catch (Exception e) {
+ ;
+ }
+ }
+
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("1-a sadly, returning a null socket");
+ return;
+ }
+
+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n";
+
+ dbg("requesting: " + req1);
+
+ if (proxy_auth) {
+ if (proxy_auth_string == null) {
+ ProxyPasswdDialog pp = new ProxyPasswdDialog(proxyHost, proxyPort, proxy_auth_basic_realm);
+ pp.queryUser();
+ proxy_auth_string = pp.getAuth();
+ }
+ //dbg("auth1: " + proxy_auth_string);
+ String auth2 = Base64Coder.encodeString(proxy_auth_string);
+ //dbg("auth2: " + auth2);
+ req1 += "Proxy-Authorization: Basic " + auth2 + "\r\n";
+ //dbg("req1: " + req1);
+ dbg("added Proxy-Authorization: Basic ... to request");
+ }
+ req1 += "\r\n";
+
+ try {
+ proxy_os.write(req1.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied: " + reply.trim());
+
+ if (reply.indexOf("HTTP/1.") == 0 && reply.indexOf(" 407 ") > 0) {
+ proxy_auth = true;
+ proxySock.close();
+ } else if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2-a sadly, returning a null socket");
+ return;
+ }
+ }
+ } catch(Exception e) {
+ dbg("sock prob: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line: " + line.trim());
+ if (proxy_auth) {
+ String uc = line.toLowerCase();
+ if (uc.indexOf("proxy-authenticate:") == 0) {
+ if (uc.indexOf(" basic ") >= 0) {
+ int idx = uc.indexOf(" realm");
+ if (idx >= 0) {
+ proxy_auth_basic_realm = uc.substring(idx+1);
+ }
+ }
+ }
+ }
+ if (line.equals("\r\n") || line.equals("\n")) {
+ break;
+ }
+ }
+ if (!proxy_auth || proxy_auth_basic_realm.equals("")) {
+ break;
+ }
+ }
+ }
+
+ public SSLSocket proxy_socket(SSLSocketFactory factory) {
+ Properties props = null;
+ String proxyHost = null;
......@@ -912,44 +1016,10 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ dbg("User said host: " + pd.getHost() + " port: " + pd.getPort());
+ }
+
+ dbg("proxy_in_use psocket:");
+ proxySock = psocket(proxyHost, proxyPort);
+ proxy_helper(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("1-a sadly, returning a null socket");
+ return null;
+ }
+ String hp = host + ":" + port;
+
+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n\r\n";
+
+ dbg("requesting1: " + req1);
+
+ try {
+ proxy_os.write(req1.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied1: " + reply.trim());
+
+ if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2-a sadly, returning a null socket");
+ return null;
+ }
+ }
+ } catch(Exception e) {
+ dbg("sock prob1: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line1: " + line.trim());
+ if (line.equals("\r\n") || line.equals("\n")) {
+ break;
+ }
+ }
+ } else if (viewer.CONNECT != null) {
+ dbg("viewer.CONNECT psocket:");
+ proxySock = psocket(host, port);
......@@ -991,7 +1061,6 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ break;
+ }
+ }
+
+ }
+
+ Socket sslsock = null;
......@@ -1351,6 +1420,77 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ }
+}
+
+class ProxyPasswdDialog implements ActionListener {
+ String guessedHost = null;
+ String guessedPort = null;
+ String guessedUser = null;
+ String guessedPasswd = null;
+ String realm = null;
+ /*
+ * this is the gui to show the user the cert and info and ask
+ * them if they want to continue using this cert.
+ */
+
+ Button ok;
+ Dialog dialog;
+ TextField entry1;
+ TextField entry2;
+ String reply1 = "";
+ String reply2 = "";
+
+ ProxyPasswdDialog (String h, int p, String realm) {
+ guessedHost = h;
+ try {
+ guessedPort = Integer.toString(p);
+ } catch (Exception e) {
+ guessedPort = "8080";
+ }
+ this.realm = realm;
+ }
+
+ public void queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame("Proxy Requires Username and Password");
+
+ dialog = new Dialog(frame, true);
+
+ //Label label = new Label("Please Enter your Web Proxy Username in the top Entry and Password in the bottom Entry", Label.CENTER);
+ TextArea label = new TextArea("Please Enter your Web Proxy\nUsername in the Top Entry and\nPassword in the Bottom Entry,\nand then press OK.", 4, 20, TextArea.SCROLLBARS_NONE);
+ entry1 = new TextField(30);
+ entry2 = new TextField(30);
+ entry2.setEchoChar('*');
+ ok = new Button("OK");
+ ok.addActionListener(this);
+
+ dialog.setLayout(new BorderLayout());
+ dialog.add("North", label);
+ dialog.add("Center", entry1);
+ dialog.add("South", entry2);
+ dialog.add("East", ok);
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til OK or Cancel pressed. */
+ return;
+ }
+
+ public String getAuth() {
+ return reply1 + ":" + reply2;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == ok) {
+ reply1 = entry1.getText();
+ reply2 = entry2.getText();
+ //dialog.dispose();
+ dialog.hide();
+ }
+ }
+}
+
+class ClientCertDialog implements ActionListener {
+
+ Button ok;
......@@ -1531,6 +1671,127 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ }
+ }
+}
+
+class Base64Coder {
+
+ // Mapping table from 6-bit nibbles to Base64 characters.
+ private static char[] map1 = new char[64];
+ static {
+ int i=0;
+ for (char c='A'; c<='Z'; c++) map1[i++] = c;
+ for (char c='a'; c<='z'; c++) map1[i++] = c;
+ for (char c='0'; c<='9'; c++) map1[i++] = c;
+ map1[i++] = '+'; map1[i++] = '/'; }
+
+ // Mapping table from Base64 characters to 6-bit nibbles.
+ private static byte[] map2 = new byte[128];
+ static {
+ for (int i=0; i<map2.length; i++) map2[i] = -1;
+ for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
+
+ /**
+ * Encodes a string into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param s a String to be encoded.
+ * @return A String with the Base64 encoded data.
+ */
+ public static String encodeString (String s) {
+ return new String(encode(s.getBytes())); }
+
+ /**
+ * Encodes a byte array into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param in an array containing the data bytes to be encoded.
+ * @return A character array with the Base64 encoded data.
+ */
+ public static char[] encode (byte[] in) {
+ return encode(in,in.length); }
+
+ /**
+ * Encodes a byte array into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param in an array containing the data bytes to be encoded.
+ * @param iLen number of bytes to process in <code>in</code>.
+ * @return A character array with the Base64 encoded data.
+ */
+ public static char[] encode (byte[] in, int iLen) {
+ int oDataLen = (iLen*4+2)/3; // output length without padding
+ int oLen = ((iLen+2)/3)*4; // output length including padding
+ char[] out = new char[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++] & 0xff;
+ int i1 = ip < iLen ? in[ip++] & 0xff : 0;
+ int i2 = ip < iLen ? in[ip++] & 0xff : 0;
+ int o0 = i0 >>> 2;
+ int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
+ int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
+ int o3 = i2 & 0x3F;
+ out[op++] = map1[o0];
+ out[op++] = map1[o1];
+ out[op] = op < oDataLen ? map1[o2] : '='; op++;
+ out[op] = op < oDataLen ? map1[o3] : '='; op++; }
+ return out; }
+
+ /**
+ * Decodes a string from Base64 format.
+ * @param s a Base64 String to be decoded.
+ * @return A String containing the decoded data.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static String decodeString (String s) {
+ return new String(decode(s)); }
+
+ /**
+ * Decodes a byte array from Base64 format.
+ * @param s a Base64 String to be decoded.
+ * @return An array containing the decoded data bytes.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static byte[] decode (String s) {
+ return decode(s.toCharArray()); }
+
+ /**
+ * Decodes a byte array from Base64 format.
+ * No blanks or line breaks are allowed within the Base64 encoded data.
+ * @param in a character array containing the Base64 encoded data.
+ * @return An array containing the decoded data bytes.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static byte[] decode (char[] in) {
+ int iLen = in.length;
+ if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
+ while (iLen > 0 && in[iLen-1] == '=') iLen--;
+ int oLen = (iLen*3) / 4;
+ byte[] out = new byte[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++];
+ int i1 = in[ip++];
+ int i2 = ip < iLen ? in[ip++] : 'A';
+ int i3 = ip < iLen ? in[ip++] : 'A';
+ if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int b0 = map2[i0];
+ int b1 = map2[i1];
+ int b2 = map2[i2];
+ int b3 = map2[i3];
+ if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int o0 = ( b0 <<2) | (b1>>>4);
+ int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
+ int o2 = ((b2 & 3)<<6) | b3;
+ out[op++] = (byte)o0;
+ if (op<oLen) out[op++] = (byte)o1;
+ if (op<oLen) out[op++] = (byte)o2; }
+ return out; }
+
+ // Dummy constructor.
+ private Base64Coder() {}
+
+}
diff -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 2007-09-03 23:22:13.000000000 -0400
......
......@@ -2644,8 +2644,8 @@ diff -Naur JavaViewer.orig/RfbProto.java JavaViewer/RfbProto.java
// }
diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
--- JavaViewer.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500
+++ JavaViewer/SSLSocketToMe.java 2008-04-15 12:54:51.000000000 -0400
@@ -0,0 +1,1456 @@
+++ JavaViewer/SSLSocketToMe.java 2009-06-18 09:47:22.000000000 -0400
@@ -0,0 +1,1717 @@
+/*
+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
+ *
......@@ -2701,6 +2701,7 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ public DataInputStream is = null;
+ public OutputStream os = null;
+
+ String proxy_auth_string = null;
+ String proxy_dialog_host = null;
+ int proxy_dialog_port = 0;
+
......@@ -3219,9 +3220,9 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ user_wants_to_see_cert = false;
+ } else {
+ bcd = new BrowserCertsDialog(serv, host + ":" + port);
+ dbg("bcd START");
+ dbg("browser certs dialog START");
+ bcd.queryUser();
+ dbg("bcd DONE");
+ dbg("browser certs dialog DONE");
+ if (bcd.showCertDialog) {
+ String msg = "user wants to see cert";
+ dbg(msg);
......@@ -3229,14 +3230,17 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ throw new SSLHandshakeException(msg);
+ } else {
+ user_wants_to_see_cert = false;
+ dbg("bcd: user said yes, accept it");
+ dbg("browser certs dialog: user said yes, accept it");
+ }
+ }
+
+ } catch (SSLHandshakeException eh) {
+ dbg("Could not automatically verify Server.");
+ dbg("msg: " + eh.getMessage());
+ String getoutstr = "GET /index.vnc HTTP/1.0\r\nConnection: close\r\n\r\n";
+
+ OutputStream os = socket.getOutputStream();
+ os.write(getoutstr.getBytes());
+ socket.close();
+ socket = null;
+
......@@ -3272,6 +3276,8 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ * close socket now, we will reopen after
+ * dialog if user agrees to use the cert.
+ */
+ os = socket.getOutputStream();
+ os.write(getoutstr.getBytes());
+ socket.close();
+ socket = null;
+
......@@ -3293,6 +3299,15 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ throw new IOException(ehand2.getMessage());
+ }
+
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ ;
+ }
+ socket = null;
+ }
+
+ /*
+ * Now connect a 3rd time, using the cert
+ * retrieved during connection 2 (that the user
......@@ -3377,6 +3392,95 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ return n;
+ }
+
+ private void proxy_helper(String proxyHost, int proxyPort) {
+
+ boolean proxy_auth = false;
+ String proxy_auth_basic_realm = "";
+ String hp = host + ":" + port;
+ dbg("proxy_helper: " + proxyHost + ":" + proxyPort + " hp: " + hp);
+
+ for (int k=0; k < 2; k++) {
+ dbg("proxy_in_use psocket:");
+
+ if (proxySock != null) {
+ try {
+ proxySock.close();
+ } catch (Exception e) {
+ ;
+ }
+ }
+
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("1-a sadly, returning a null socket");
+ return;
+ }
+
+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n";
+
+ dbg("requesting: " + req1);
+
+ if (proxy_auth) {
+ if (proxy_auth_string == null) {
+ ProxyPasswdDialog pp = new ProxyPasswdDialog(proxyHost, proxyPort, proxy_auth_basic_realm);
+ pp.queryUser();
+ proxy_auth_string = pp.getAuth();
+ }
+ //dbg("auth1: " + proxy_auth_string);
+ String auth2 = Base64Coder.encodeString(proxy_auth_string);
+ //dbg("auth2: " + auth2);
+ req1 += "Proxy-Authorization: Basic " + auth2 + "\r\n";
+ //dbg("req1: " + req1);
+ dbg("added Proxy-Authorization: Basic ... to request");
+ }
+ req1 += "\r\n";
+
+ try {
+ proxy_os.write(req1.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied: " + reply.trim());
+
+ if (reply.indexOf("HTTP/1.") == 0 && reply.indexOf(" 407 ") > 0) {
+ proxy_auth = true;
+ proxySock.close();
+ } else if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2-a sadly, returning a null socket");
+ return;
+ }
+ }
+ } catch(Exception e) {
+ dbg("sock prob: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line: " + line.trim());
+ if (proxy_auth) {
+ String uc = line.toLowerCase();
+ if (uc.indexOf("proxy-authenticate:") == 0) {
+ if (uc.indexOf(" basic ") >= 0) {
+ int idx = uc.indexOf(" realm");
+ if (idx >= 0) {
+ proxy_auth_basic_realm = uc.substring(idx+1);
+ }
+ }
+ }
+ }
+ if (line.equals("\r\n") || line.equals("\n")) {
+ break;
+ }
+ }
+ if (!proxy_auth || proxy_auth_basic_realm.equals("")) {
+ break;
+ }
+ }
+ }
+
+ public SSLSocket proxy_socket(SSLSocketFactory factory) {
+ Properties props = null;
+ String proxyHost = null;
......@@ -3483,44 +3587,10 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ dbg("User said host: " + pd.getHost() + " port: " + pd.getPort());
+ }
+
+ dbg("proxy_in_use psocket:");
+ proxySock = psocket(proxyHost, proxyPort);
+ proxy_helper(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("1-a sadly, returning a null socket");
+ return null;
+ }
+ String hp = host + ":" + port;
+
+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n\r\n";
+
+ dbg("requesting1: " + req1);
+
+ try {
+ proxy_os.write(req1.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied1: " + reply.trim());
+
+ if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2-a sadly, returning a null socket");
+ return null;
+ }
+ }
+ } catch(Exception e) {
+ dbg("sock prob1: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line1: " + line.trim());
+ if (line.equals("\r\n") || line.equals("\n")) {
+ break;
+ }
+ }
+ } else if (viewer.CONNECT != null) {
+ dbg("viewer.CONNECT psocket:");
+ proxySock = psocket(host, port);
......@@ -3562,7 +3632,6 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ break;
+ }
+ }
+
+ }
+
+ Socket sslsock = null;
......@@ -3922,6 +3991,77 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ }
+}
+
+class ProxyPasswdDialog implements ActionListener {
+ String guessedHost = null;
+ String guessedPort = null;
+ String guessedUser = null;
+ String guessedPasswd = null;
+ String realm = null;
+ /*
+ * this is the gui to show the user the cert and info and ask
+ * them if they want to continue using this cert.
+ */
+
+ Button ok;
+ Dialog dialog;
+ TextField entry1;
+ TextField entry2;
+ String reply1 = "";
+ String reply2 = "";
+
+ ProxyPasswdDialog (String h, int p, String realm) {
+ guessedHost = h;
+ try {
+ guessedPort = Integer.toString(p);
+ } catch (Exception e) {
+ guessedPort = "8080";
+ }
+ this.realm = realm;
+ }
+
+ public void queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame("Proxy Requires Username and Password");
+
+ dialog = new Dialog(frame, true);
+
+ //Label label = new Label("Please Enter your Web Proxy Username in the top Entry and Password in the bottom Entry", Label.CENTER);
+ TextArea label = new TextArea("Please Enter your Web Proxy\nUsername in the Top Entry and\nPassword in the Bottom Entry,\nand then press OK.", 4, 20, TextArea.SCROLLBARS_NONE);
+ entry1 = new TextField(30);
+ entry2 = new TextField(30);
+ entry2.setEchoChar('*');
+ ok = new Button("OK");
+ ok.addActionListener(this);
+
+ dialog.setLayout(new BorderLayout());
+ dialog.add("North", label);
+ dialog.add("Center", entry1);
+ dialog.add("South", entry2);
+ dialog.add("East", ok);
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til OK or Cancel pressed. */
+ return;
+ }
+
+ public String getAuth() {
+ return reply1 + ":" + reply2;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == ok) {
+ reply1 = entry1.getText();
+ reply2 = entry2.getText();
+ //dialog.dispose();
+ dialog.hide();
+ }
+ }
+}
+
+class ClientCertDialog implements ActionListener {
+
+ Button ok;
......@@ -4102,6 +4242,127 @@ diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
+ }
+ }
+}
+
+class Base64Coder {
+
+ // Mapping table from 6-bit nibbles to Base64 characters.
+ private static char[] map1 = new char[64];
+ static {
+ int i=0;
+ for (char c='A'; c<='Z'; c++) map1[i++] = c;
+ for (char c='a'; c<='z'; c++) map1[i++] = c;
+ for (char c='0'; c<='9'; c++) map1[i++] = c;
+ map1[i++] = '+'; map1[i++] = '/'; }
+
+ // Mapping table from Base64 characters to 6-bit nibbles.
+ private static byte[] map2 = new byte[128];
+ static {
+ for (int i=0; i<map2.length; i++) map2[i] = -1;
+ for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
+
+ /**
+ * Encodes a string into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param s a String to be encoded.
+ * @return A String with the Base64 encoded data.
+ */
+ public static String encodeString (String s) {
+ return new String(encode(s.getBytes())); }
+
+ /**
+ * Encodes a byte array into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param in an array containing the data bytes to be encoded.
+ * @return A character array with the Base64 encoded data.
+ */
+ public static char[] encode (byte[] in) {
+ return encode(in,in.length); }
+
+ /**
+ * Encodes a byte array into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param in an array containing the data bytes to be encoded.
+ * @param iLen number of bytes to process in <code>in</code>.
+ * @return A character array with the Base64 encoded data.
+ */
+ public static char[] encode (byte[] in, int iLen) {
+ int oDataLen = (iLen*4+2)/3; // output length without padding
+ int oLen = ((iLen+2)/3)*4; // output length including padding
+ char[] out = new char[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++] & 0xff;
+ int i1 = ip < iLen ? in[ip++] & 0xff : 0;
+ int i2 = ip < iLen ? in[ip++] & 0xff : 0;
+ int o0 = i0 >>> 2;
+ int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
+ int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
+ int o3 = i2 & 0x3F;
+ out[op++] = map1[o0];
+ out[op++] = map1[o1];
+ out[op] = op < oDataLen ? map1[o2] : '='; op++;
+ out[op] = op < oDataLen ? map1[o3] : '='; op++; }
+ return out; }
+
+ /**
+ * Decodes a string from Base64 format.
+ * @param s a Base64 String to be decoded.
+ * @return A String containing the decoded data.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static String decodeString (String s) {
+ return new String(decode(s)); }
+
+ /**
+ * Decodes a byte array from Base64 format.
+ * @param s a Base64 String to be decoded.
+ * @return An array containing the decoded data bytes.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static byte[] decode (String s) {
+ return decode(s.toCharArray()); }
+
+ /**
+ * Decodes a byte array from Base64 format.
+ * No blanks or line breaks are allowed within the Base64 encoded data.
+ * @param in a character array containing the Base64 encoded data.
+ * @return An array containing the decoded data bytes.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static byte[] decode (char[] in) {
+ int iLen = in.length;
+ if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
+ while (iLen > 0 && in[iLen-1] == '=') iLen--;
+ int oLen = (iLen*3) / 4;
+ byte[] out = new byte[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++];
+ int i1 = in[ip++];
+ int i2 = ip < iLen ? in[ip++] : 'A';
+ int i3 = ip < iLen ? in[ip++] : 'A';
+ if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int b0 = map2[i0];
+ int b1 = map2[i1];
+ int b2 = map2[i2];
+ int b3 = map2[i3];
+ if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int o0 = ( b0 <<2) | (b1>>>4);
+ int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
+ int o2 = ((b2 & 3)<<6) | b3;
+ out[op++] = (byte)o0;
+ if (op<oLen) out[op++] = (byte)o1;
+ if (op<oLen) out[op++] = (byte)o2; }
+ return out; }
+
+ // Dummy constructor.
+ private Base64Coder() {}
+
+}
diff -Naur JavaViewer.orig/VncCanvas.java JavaViewer/VncCanvas.java
--- JavaViewer.orig/VncCanvas.java 2005-11-21 18:50:18.000000000 -0500
+++ JavaViewer/VncCanvas.java 2007-05-31 15:33:20.000000000 -0400
......
2009-06-18 Karl Runge <runge@karlrunge.com>
* classes/ssl: java viewer now handles auth-basic proxy logins.
* misc/enhanced_tightvnc_viewer: update ssvnc.
2009-06-14 Karl Runge <runge@karlrunge.com>
* x11vnc: Add X11VNC_REFLECT_PASSWORD env. var. for -reflect mode.
Message to user about compiz problems suggesting -noxdamage.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Enhanced TightVNC Viewer (SSVNC: SSL/SSH VNC viewer)
Copyright (c) 2006-2008 Karl J. Runge <runge@karlrunge.com>
Copyright (c) 2006-2009 Karl J. Runge <runge@karlrunge.com>
All rights reserved.
These bundles provide 1) An enhanced TightVNC Viewer on Unix, 2) Binaries
......@@ -108,7 +108,8 @@ The enhanced TightVNC viewer features are:
"Terminal Services" mode (uses x11vnc on the remote side).
(the following features only apply to the bundled Unix tightvnc viewer)
(the following features only apply to the bundled Unix tightvnc viewer
including MacOS X)
- rfbNewFBSize VNC support (screen resizing)
......@@ -119,10 +120,22 @@ The enhanced TightVNC viewer features are:
- Support for the ZYWRLE encoding, a wavelet based extension to
ZRLE to improve compression of motion video and photo regions.
- TurboVNC support (VirtualGL's modified TightVNC encoding;
requires TurboJPEG library)
- Pipelined Updates of the framebuffer as in TurboVNC (asks for
the next update before the current one has finished downloading;
this gives some speedup on high latency connections.)
- Cursor alphablending with x11vnc at 32bpp (-alpha option)
- Option "-unixpw ..." for use with "x11vnc -unixpw" login dialogs.
- VeNCrypt SSL/TLS VNC encryption support (used by VeNCrypt,
QEMU, ggi, libvirt/virt-manager/xen, vinagre/gvncviewer/gtk-vnc)
- ANONTLS SSL/TLS VNC encryption support (used by vino)
- Support for UltraVNC extensions: Single Window, Disable
Server-side Input, 1/n Server side scaling, Text Chat (shell
terminal UI). Both UltraVNC and x11vnc servers support these
......@@ -141,6 +154,11 @@ The enhanced TightVNC viewer features are:
- Support for UltraVNC DSM Encryption Plugin mode. (ARC4 and
AESV2, and MSRC4)
- Support for UltraVNC MS-Logon authentication (NOTE: the UltraVNC
MS-Logon key exchange implementation is very weak; an eavesdropper
on the network can recover your Windows password easily; you
need to use an additional encrypted tunnel with MS-Logon.)
- Support for symmetric encryption (including blowfish and 3des
ciphers) to Non-UltraVNC Servers. Any server using the same
encryption method will work, e.g.: x11vnc -enc blowfish:./my.key
......@@ -174,12 +192,18 @@ The enhanced TightVNC viewer features are:
- Scrollbar width setting: -sbwidth n, the default is very thin,
2 pixels, for less distracting -ycrop usage.
- Selection text sending and receiving can be fine-tuned with the
-sendclipboard, -sendalways, and -recvtext options.
- TightVNC compression and quality levels are automatically set
based on observed network latency (n.b. not bandwidth.)
- Improvements to the Popup menu, all of these can now be changed
dynamically via the menu: ViewOnly, Toggle Bell, CursorShape
updates, X11 Cursor, Cursor Alphablending, Toggle Tight/ZRLE,
Toggle JPEG, FullColor/16bpp/8bpp (256/64/8 colors), Greyscale
for low color modes, Scaling the Viewer resolution, Escape Keys,
and others, including UltraVNC extensions.
Pipeline Updates, and others, including UltraVNC extensions.
- Maintains its own BackingStore if the X server does not
......@@ -220,7 +244,7 @@ Unix and Mac OS X:
Unpack the archive:
% gzip -dc ssvnc-1.0.21.tar.gz | tar xvf -
% gzip -dc ssvnc-1.0.22.tar.gz | tar xvf -
Run the GUI:
......@@ -228,7 +252,7 @@ Unix and Mac OS X:
% ./ssvnc/MacOSX/ssvnc (for Mac OS X)
The smaller file "ssvnc_no_windows-1.0.21.tar.gz"
The smaller file "ssvnc_no_windows-1.0.22.tar.gz"
could have been used as well.
On MacOSX you could also click on the SSVNC app icon in the Finder.
......@@ -274,8 +298,8 @@ Unix/MacOSX Install:
For the conventional source tarball it will compile and install, e.g.:
gzip -dc ssvnc-1.0.21.src.tar.gz | tar xvf -
cd ssvnc-1.0.21
gzip -dc ssvnc-1.0.22.src.tar.gz | tar xvf -
cd ssvnc-1.0.22
make config
make all
make PREFIX=/my/install/dir install
......@@ -287,7 +311,7 @@ Windows:
Unzip, using WinZip or a similar utility, the zip file:
ssvnc-1.0.21.zip
ssvnc-1.0.22.zip
Run the GUI, e.g.:
......@@ -299,7 +323,7 @@ Windows:
select Open, and then OK to launch it.
The smaller file "ssvnc_windows_only-1.0.21.zip"
The smaller file "ssvnc_windows_only-1.0.22.zip"
could have been used as well.
You can make a Windows shortcut to this program if you want to.
......@@ -439,6 +463,30 @@ Most Mac OS X and Unix OS come with the main components installed.
See the README.src for a more detailed description of dependencies.
TurboVNC Support:
----------------
TurboVNC is supported in an experimental way. To it build via the
build.unix script described in the next section, do something like:
env TURBOVNC='-L/DIR -Xlinker --rpath=/DIR -lturbojpeg' ./build.unix
where you replace /DIR with the directory where the libturbojpeg.so
(http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=166100)
is installed.
You may not need to set rpath if libturbojpeg.so is installed in a
standard location or you use LD_LIBRARY_PATH to point to it.
See the turbovnc/README in the vnc_unixsrc/vncviewer directory for
more info. You can find it in the ssvnc source tarball and also
in:
src/zips/vnc_unixsrc_vncviewer.patched.tar
More TurboVNC features will be enabled in the future.
If you need to Build:
--------------------
......@@ -685,7 +733,7 @@ For more help on other options and usage patterns run these:
See also:
http://www.karlrunge.com/x11vnc
http://www.karlrunge.com/x11vnc/#faq
http://www.karlrunge.com/x11vnc/faq.html
x11vnc -h | more
http://www.stunnel.org
......
......@@ -37,7 +37,7 @@ and also:
You can use x11vnc to create certificates if you like:
http://www.karlrunge.com/x11vnc/#faq-ssl-ca
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
Misc:
......
......@@ -249,6 +249,16 @@ if [ $use_ours = 1 ]; then
SSVNC_USE_OURS=1; export SSVNC_USE_OURS
if [ "X$SSVNC_TURBOVNC" != "X" ]; then
if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then
:
else
if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then
VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc"
fi
fi
fi
if [ "X$base" = "Xtightvncviewer" ]; then
$VNCVIEWERCMD -encodings 'copyrect tight zrle zlib hextile' "$@"
else
......
......@@ -46,8 +46,8 @@
# -showcert Only fetch the certificate using the 'openssl s_client'
# command (openssl(1) must in installed).
#
# See http://www.karlrunge.com/x11vnc/#faq-ssl-ca for details on SSL
# certificates with VNC.
# See http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca for details on
# SSL certificates with VNC.
#
# A few other args (not related to SSL and certs):
#
......@@ -115,6 +115,15 @@
#
VNCIPCMD=${VNCVIEWERCMD:-vncip}
VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
if [ "X$SSVNC_TURBOVNC" != "X" ]; then
if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then
:
else
if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then
VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc"
fi
fi
fi
#
# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc.
#
......@@ -268,6 +277,12 @@ do
;;
"-onelisten") SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
;;
"-sendclipboard") VNCVIEWER_SEND_CLIPBOARD=1; export VNCVIEWER_SEND_CLIPBOARD
;;
"-sendalways") VNCVIEWER_SEND_ALWAYS=1; export VNCVIEWER_SEND_ALWAYS
;;
"-recvtext") shift; VNCVIEWER_RECV_TEXT="$1"; export VNCVIEWER_RECV_TEXT
;;
"-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE
;;
"-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS
......@@ -751,6 +766,19 @@ if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) {
$handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE};
}
my $have_gettimeofday = 0;
eval "use Time::HiRes";
if ($@ eq "") {
$have_gettimeofday = 1;
}
sub gettime {
my $t = "0.0";
if ($have_gettimeofday) {
$t = Time::HiRes::gettimeofday();
}
return $t;
}
sub append_handshake {
my $str = shift;
if ($handshake_file) {
......@@ -1324,12 +1352,19 @@ sub vencrypt_dialog {
} elsif ($minor == 7) {
$viewer_rfb = "RFB 003.007\n";
}
syswrite($sock, $viewer_rfb, 12);
append_handshake("viewer=$viewer_rfb");
my $nsec;
my $t1 = gettime();
my $t0 = gettime();
syswrite($sock, $viewer_rfb, 12);
sysread($sock, $nsec, 1);
$t1 = gettime();
$t1 = sprintf("%.6f", $t1 - $t0);
append_handshake("viewer=$viewer_rfb");
append_handshake("latency=$t1\n");
vdie if $nsec eq "";
$nsec = unpack("C", $nsec);
......
......@@ -472,7 +472,7 @@ proc help {} {
steps of setting up a Certificate Authority (CA) to sign the VNC server
and/or VNC client Certs, that can be used instead and avoids the need to
manually verify every cert while still authenticating every connection.
More info: http://www.karlrunge.com/x11vnc/#faq-ssl-ca
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
See the cmdline option -cacert file below in 'SSL Certificates'
for setting a default ServerCert/CA Cert.
......@@ -662,7 +662,7 @@ proc help {} {
See also these links for more information:
http://www.karlrunge.com/x11vnc/#faq-ssl-tunnel-ext
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
http://www.stunnel.org
http://www.tightvnc.com
}
......@@ -828,8 +828,8 @@ proc help {} {
See the ss_vncviewer description and x11vnc FAQ for info on proxies:
http://www.karlrunge.com/x11vnc/#ss_vncviewer
http://www.karlrunge.com/x11vnc/#faq-ssl-java-viewer-proxy
http://www.karlrunge.com/x11vnc/faq.html#ss_vncviewer
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy
SSH Proxies/Gateways:
......@@ -1719,7 +1719,7 @@ proc help_certs {} {
See the x11vnc and STUNNEL documentation for how to create and use PEM
certificate files:
http://www.karlrunge.com/x11vnc/#faq-ssl-tunnel-ext
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
http://www.karlrunge.com/x11vnc/ssl.html
http://www.stunnel.org
......@@ -1903,7 +1903,7 @@ set msg {
x11vnc has an experiment Client-Side caching scheme "-ncache n"
that can give nice speedups. But there are some drawbacks
because the cache-region is visible and uses much RAM.
http://www.karlrunge.com/x11vnc/#faq-client-caching
http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
X11VNC Options:
......@@ -2644,7 +2644,8 @@ proc set_defaults {} {
global defs env
global mycert svcert crtdir crlfil
global use_alpha use_grab use_ssl use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
global use_alpha use_turbovnc use_grab use_ssl use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
global use_send_clipboard use_send_always
global disable_all_encryption
global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
global compresslevel_text quality_text
......@@ -2683,6 +2684,9 @@ proc set_defaults {} {
set defs(use_raise_on_beep) 0
set defs(use_bgr233) 0
set defs(use_alpha) 0
set defs(use_send_clipboard) 0
set defs(use_send_always) 0
set defs(use_turbovnc) 0
set defs(server_vencrypt) 0
set defs(server_anondh) 0
set defs(use_grab) 0
......@@ -2825,6 +2829,7 @@ proc set_defaults {} {
proc do_viewer_windows {n} {
global use_alpha use_grab use_x11cursor use_nobell use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
global use_nojpeg use_raise_on_beep use_compresslevel use_quality
global use_send_clipboard use_send_always
global change_vncviewer change_vncviewer_path vncviewer_realvnc4
global use_listen disable_ssl_workarounds disable_ssl_workarounds_type env
......@@ -5543,6 +5548,7 @@ proc reset_stunnel_extra_opts {} {
set env(SSVNC_MULTIPLE_LISTEN) $ssvnc_multiple_listen0
}
set env(SSVNC_ULTRA_DSM) ""
set env(SSVNC_TURBOVNC) ""
}
proc launch_unix {hp} {
......@@ -5988,6 +5994,15 @@ proc launch_unix {hp} {
if {$use_alpha} {
set cmd "$cmd -alpha"
}
if {$use_send_clipboard} {
set cmd "$cmd -sendclipboard"
}
if {$use_send_always} {
set cmd "$cmd -sendalways"
}
if {$use_turbovnc} {
set env(SSVNC_TURBOVNC) 1
}
if {$use_grab} {
set cmd "$cmd -grab"
}
......@@ -8045,7 +8060,7 @@ proc create_cert {{name ""}} {
For more information see:
http://www.karlrunge.com/x11vnc/ssl.html
http://www.karlrunge.com/x11vnc/#faq-ssl-tunnel-int
http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-int
The first one describes how to use x11vnc to create Certificate
Authority (CA) certificates in addition to self-signed ones.
......@@ -10300,9 +10315,9 @@ proc ts_xlogin_dialog {} {
not x11vnc.
Note that the GDM display manager has a setting KillInitClients in
gdm.conf that will kill x11vnc right after you log in, and so you
would have to repeat the whole process ('Connect' button) to attach to
your session. See http://www.karlrunge.com/x11vnc/#faq-display-manager
gdm.conf that will kill x11vnc right after you log in, and so you would
have to repeat the whole process ('Connect' button) to attach to your
session. See http://www.karlrunge.com/x11vnc/faq.html#faq-display-manager
for more info.
}
.xlog.f.t insert end $msg
......@@ -10444,7 +10459,7 @@ proc ts_ncache_dialog {} {
for the caching region. So 10 means use 10 times the RAM to store
pixmaps. The default is 8.
More info: http://www.karlrunge.com/x11vnc/#faq-client-caching
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
}
.nche.f.t insert end $msg
......@@ -10505,7 +10520,7 @@ proc ts_x11vnc_opts_dialog {} {
-repeat -cursor -wmdt
-nowireframe -ncache_cr -speeds
More info: http://www.karlrunge.com/x11vnc/#faq-cmdline-opts
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-cmdline-opts
}
# In Auto Port put a starting port for x11vnc to try autoprobing
# instead of the default 5900. It starts at the value you supply and
......@@ -10571,7 +10586,7 @@ proc ts_filexfer_dialog {} {
The defaults for the SSVNC viewer package are TightVNC on
Windows and UltraVNC on Unix.
For more info see: http://www.karlrunge.com/x11vnc/#faq-filexfer
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-filexfer
}
.xfer.f.t insert end $msg
......@@ -10673,7 +10688,7 @@ proc ts_cups_dialog {} {
http://localhost:port/printers/printername
For more info see: http://www.karlrunge.com/x11vnc/#faq-cups
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
}
# The "Manage 'ServerName' in .cups/client.conf for me" setting is usually
......@@ -10946,7 +10961,7 @@ proc cups_dialog {} {
that knows about your Windows printer, you might have better luck with
that instead of using SMB. Set 'Local CUPS Server' to it.
For more info see: http://www.karlrunge.com/x11vnc/#faq-cups
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
}
.cups.f.t insert end $msg
......@@ -11058,7 +11073,7 @@ proc ts_sound_dialog {} {
And esd's LD_PRELOAD is broken on 64+32bit Linux (x86_64).
And so this mode is not working well currently...
For more info see: http://www.karlrunge.com/x11vnc/#faq-sound
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
}
......@@ -11187,7 +11202,7 @@ proc sound_dialog {} {
a numerical port to specify non-localhost connections, e.g. to another
nearby machine.
For more info see: http://www.karlrunge.com/x11vnc/#faq-sound
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
}
.snd.f.t insert end $msg
......@@ -11972,7 +11987,7 @@ proc smb_dialog {} {
the share, become root and umount the shares manually ("smbumount
/path/to/share", etc.)
For more info see: http://www.karlrunge.com/x11vnc/#faq-smb-shares
For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-smb-shares
}
set msg2 {
......@@ -12244,6 +12259,29 @@ proc help_ssvncviewer_opts {} {
Use the x11vnc alpha hack for translucent cursors (requires Unix,
32bpp and same endianness)
TurboVNC:
If available on your platform, use a ssvncviewer compiled with
TurboVNC support. This is based on the the VirtualGL project:
http://www.sourceforge.net/projects/virtualgl You will need
to install the VirtualGL's TurboJPEG library too.
Currently (May/2009) only Linux.i686, Linux.x86_64, and
Darwin.i386 have vncviewer.turbovnc binaries shipped in the
ssvnc bundles. See the build instructions for how you might
compile your own.
Send CLIPBOARD not PRIMARY:
When sending locally selected text to the VNC server side,
send the CLIPBOARD selection instead of the PRIMARY selection.
Send Selection Every time:
Send selected text to the VNC server side every time the mouse
focus enters the main VNC Viewer window instead only when it
appears to have changed since the last send.
Scaling:
Use viewer-side (i.e. local) scaling of the VNC screen. Supply
......@@ -12304,13 +12342,50 @@ proc help_ssvncviewer_opts {} {
VNCVIEWER_X11CURSOR (-x11cursor, see Use X11 Cursor above)
VNCVIEWER_RAWLOCAL (-rawlocal, see Use Raw Local above)
VNCVIEWER_ESCAPE (-escape, see Escape Keys above)
SSVNC_MULTIPLE_LISTEN (-multilisten, see Mulitple LISTEN above)
VNCVIEWER_ULTRADSM (-ultradsm)
VNCVIEWER_SEND_CLIPBOARD (-sendclipboard)
VNCVIEWER_SEND_ALWAYS (-sendalways)
VNCVIEWER_RECV_TEXT (-recvtext clipboard/primary/both)
VNCVIEWER_NO_CUTBUFFER (do not send CUTBUFFER0 as fallback)
SSVNC_MULTIPLE_LISTEN (-multilisten, see Multiple LISTEN above)
SSVNC_TURBOVNC (see TurboVNC above)
SSVNC_UNIXPW (-unixpw)
SSVNC_UNIXPW_NOESC (do not send escape in -unixpw mode)
SSVNC_SCALE (-scale, see Scaling above)
SSVNC_NOSOLID (do not do solid region speedup in
scaling mode.)
SSVNC_PRESERVE_ENCODING (do not switch to ZRLE when scaling)
Misc (special usage or debugging):
SSVNC_NO_ULTRA_DSM
SSVNC_ULTRA_FTP_JAR
SSVNC_SCALE_STATS
SSVNC_DEBUG_RELEASE
SSVNC_DEBUG_ESCAPE_KEYS
SSVNC_NO_MAYBE_SYNC
SSVNC_MAX_LISTEN
SSVNC_LISTEN_ONCE
SSVNC_EXIT_DEBUG
SSVNC_DEBUG_CHAT
SSVNC_NO_MESSAGE_POPUP
SSVNC_SET_SECURITY_TYPE
SSVNC_PREDIGESTED_HANDSHAKE
SSVNC_SKIP_RFB_PROTOCOL_VERSION
SSVNC_DEBUG_SEC_TYPES
SSVNC_DEBUG_MSLOGON
SSVNC_DEBUG_RECTS
SSVNC_DEBUG_CHAT
SSVNC_DELAY_SYNC
SSVNC_DEBUG_SELECTION
SSVNC_REPEATER
SSVNC_VENCRYPT_DEBUG
SSVNC_STUNNEL_DEBUG
SSVNC_TEST_SEC_TYPE
SSVNC_LIM_ACCEPT_PRELOAD
SSVNC_EXTRA_SLEEP
SSVNC_SOCKS5
}
.av.f.t insert end $msg
......@@ -12660,10 +12735,17 @@ proc ultra_dsm_dialog {} {
set msg {
On Unix with the provided SSVNC vncviewer, you can connect to an UltraVNC
server that is using one of its encryption plugins: MSRC4, ARC4, or AESV2.
server that is using one of its DSM encryption plugins: MSRC4, ARC4, AESV2.
More info at: http://www.uvnc.com/features/encryption.html
IMPORTANT: The UltraVNC DSM implementation contains unfixed errors
that could allow an eavesdropper to recover the session key or traffic
relatively easily. They often do not provide strong encryption, but
only provide basic obscurity instead. Do not use them with critical data.
See the bottom of this help text for how to use symmetric encryption with
NON-UltraVNC servers (for example, x11vnc 0.9.5 or later).
Non-UltraVNC servers (for example, x11vnc 0.9.5 or later). This mode does
not suffer the shortcomings of the UltraVNC DSM implementation.
You will need to specify the corresponding UltraVNC encryption key (created
by you using an UltraVNC server or viewer). It is usually called 'rc4.key'
......@@ -14070,7 +14152,8 @@ proc set_advanced_options {} {
proc set_ssvncviewer_options {} {
global is_windows darwin_cotvnc
global use_ssh use_sshssl use_x11cursor use_rawlocal use_popupfix use_alpha use_grab use_nobell
global use_ssh use_sshssl use_x11cursor use_rawlocal use_popupfix use_alpha use_turbovnc use_grab use_nobell
global use_send_clipboard use_send_always
global ssvnc_scale ssvnc_escape
global server_vencrypt server_anondh
......@@ -14131,7 +14214,22 @@ proc set_ssvncviewer_options {} {
incr i
checkbutton .os.b$i -anchor w -variable use_alpha -text \
"Cursor alphablending (32bpp required)"
"Cursor Alphablending (32bpp required)"
lappend darwinlist .os.b$i; if {$darwin_cotvnc} {.os.b$i configure -state disabled}
incr i
checkbutton .os.b$i -anchor w -variable use_turbovnc -text \
"TurboVNC (if available on platform)"
lappend darwinlist .os.b$i; if {$darwin_cotvnc} {.os.b$i configure -state disabled}
incr i
checkbutton .os.b$i -anchor w -variable use_send_clipboard -text \
"Send CLIPBOARD not PRIMARY"
lappend darwinlist .os.b$i; if {$darwin_cotvnc} {.os.b$i configure -state disabled}
incr i
checkbutton .os.b$i -anchor w -variable use_send_always -text \
"Send Selection Every time"
lappend darwinlist .os.b$i; if {$darwin_cotvnc} {.os.b$i configure -state disabled}
incr i
......@@ -14678,6 +14776,7 @@ proc disable_encryption {} {
proc set_options {} {
global use_alpha use_grab use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
global use_send_clipboard use_send_always
global compresslevel_text quality_text
global env is_windows darwin_cotvnc uname
global use_listen
......
......@@ -137,8 +137,11 @@ do
if [ "X$SSVNC_BUILD_STATIC" = "X" ]; then
break
fi
for dir in /usr/lib /lib /usr/local/lib /usr/pkg/lib /usr/sfw/lib /usr/openwin/lib
for dir in $SSVNC_STATIC_DIRS /usr/lib /lib /usr/local/lib /usr/pkg/lib /usr/sfw/lib /usr/openwin/lib
do
if [ "X$dir" = "X" ]; then
continue
fi
if [ "$name" = "Linux.x86_64" -o "$name" = "Linux.ppc64" ] ; then
dir64=`echo "$dir" | sed -e 's,lib,lib64,'`
if [ "X$SSVNC_BUILD_NO_LINUX64" != "X" ]; then
......@@ -149,7 +152,9 @@ do
fi
try="$dir/$liba"
if [ -f $try ]; then
echo cp -p "$try" $libs
cp -p "$try" $libs
break
fi
done
done
......@@ -279,7 +284,11 @@ if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then
make depend
echo $PATH
if [ "X$TURBOVNC" = "X" ]; then
make all
else
make CCOPTIONS="-DTURBOVNC $CPPFLAGS_OS" EXTRA_LIBRARIES="$TURBOVNC" all
fi
ls -l vncviewer/vncviewer
cd "$start"
src=$tmp/vnc_unixsrc/vncviewer/vncviewer
......@@ -298,6 +307,9 @@ if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then
if [ `uname` = "Darwin" ]; then
suff=".x11"
fi
if [ "X$TURBOVNC" != "X" ]; then
suff="$suff.turbovnc"
fi
echo cp -p $src $dest/vncviewer$suff
sleep 1
cp -p $src $dest/vncviewer$suff || exit 1
......
......@@ -5,13 +5,13 @@
.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de
.\" Copyright (C) 2000,2001 Red Hat, Inc.
.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru>
.\" Copyright (C) 2006-2008 Karl J. Runge <runge@karlrunge.com>
.\" Copyright (C) 2006-2009 Karl J. Runge <runge@karlrunge.com>
.\"
.\" You may distribute under the terms of the GNU General Public
.\" License as specified in the file LICENCE.TXT that comes with the
.\" TightVNC distribution.
.\"
.TH ssvncviewer 1 "December 2008" "" "SSVNC"
.TH ssvncviewer 1 "June 2009" "" "SSVNC"
.SH NAME
ssvncviewer \- an X viewer client for VNC
.SH SYNOPSIS
......@@ -300,6 +300,24 @@ Disable bell.
Prefer raw encoding for localhost, default is
no, i.e. assumes you have a SSH tunnel instead.
.TP
\fB\-sendclipboard\fR
Send the X CLIPBOARD selection (i.e. Ctrl+C,
Ctrl+V) instead of the X PRIMARY selection (mouse
select and middle button paste.)
.TP
\fB\-sendalways\fR
Whenever the mouse enters the VNC viewer main
window, send the selection to the VNC server even if
it has not changed. This is like the Xt resource
translation SelectionToVNC(always)
.TP
\fB\-recvtext\fR
str When cut text is received from the VNC server,
ssvncviewer will set both the X PRIMARY and the
X CLIPBOARD local selections. To control which
is set, specify 'str' as 'primary', 'clipboard',
or 'both' (the default.)
.TP
\fB\-graball\fR
Grab the entire X server when in fullscreen mode,
needed by some old window managers like fvwm2.
......@@ -396,6 +414,18 @@ THAT supply -ultradsm to tell THIS viewer to modify the RFB
data sent so as to work with the UltraVNC Server. For some
reason, each RFB msg type must be sent twice under DSM.
.TP
\fB\-mslogon\fR \fIuser\fR
Use Windows MS Logon to an UltraVNC server. Supply the
username or "1" to be prompted. The default is to
autodetect the UltraVNC MS Logon server and prompt for
the username and password.
IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman
exchange is very weak and can be brute forced to recover
your username and password in a few hours or seconds of CPU
time. To be safe, be sure to use an additional encrypted
tunnel (e.g. SSL or SSH) for the entire VNC session.
.TP
\fB\-chatonly\fR
Try to be a client that only does UltraVNC text chat. This
mode is used by x11vnc to present a chat window on the physical
......@@ -412,6 +442,12 @@ then exit. You can save them to a file and customize them (e.g. the
keybindings and Popup menu) Then point to the file via
XENVIRONMENT or XAPPLRESDIR.
.TP
\fB\-pipeline\fR
Like TurboVNC, request the next framebuffer update as soon
as possible instead of waiting until the end of the current
framebuffer update coming in. Helps 'pipeline' the updates.
This is currently the default, use \fB-nopipeline\fR to disable.
.TP
\fB\-escape \fR\fIstr\fR
This sets the 'Escape Keys' modifier sequence and enables
escape keys mode. When the modifier keys escape sequence
......@@ -487,8 +523,10 @@ Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
Quality Level ~ -quality (both Tight and ZYWRLE)
Compress Level ~ -compresslevel
Disable JPEG: ~ -nojpeg (Tight)
Full Color ~ as many colors as local screen allows.
Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes.
Pipeline Updates ~ -pipeline
Full Color as many colors as local screen allows.
Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.
16 bit color (BGR565) ~ -16bpp / -bgr565
8 bit color (BGR233) ~ -bgr233
256 colors ~ -bgr233 default # of colors.
......@@ -506,13 +544,16 @@ Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.
Text Chat Ultravnc ext. Do Text Chat.
File Transfer Ultravnc ext. File xfer via Java helper.
Single Window Ultravnc ext. Grab a single window.
(click on the window you want).
Single Window Ultravnc ext. Grab and view a single window.
(select then click on the window you want).
Disable Remote Input Ultravnc ext. Try to prevent input and
viewing of monitor at physical display.
Note: the Ultravnc extensions only apply to servers that
support them. x11vnc/libvncserver supports some of them.
Note: the Ultravnc extensions only apply to servers that support
them. x11vnc/libvncserver supports some of them.
Send Clipboard not Primary ~ -sendclipboard
Send Selection Every time ~ -sendalways
.SH ENCODINGS
The server supplies information in whatever format is desired by the
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment