Merge branch 'fatal' of https://github.com/CendioOssman/tigervnc
diff --git a/contrib/packages/deb/ubuntu-trusty/debian/control b/contrib/packages/deb/ubuntu-trusty/debian/control
index 022f69f..f1cf906 100644
--- a/contrib/packages/deb/ubuntu-trusty/debian/control
+++ b/contrib/packages/deb/ubuntu-trusty/debian/control
@@ -3,13 +3,13 @@
Priority: optional
Maintainer: Brian P. Hinz <bphinz@users.sourceforge.net>
Standards-Version: 3.8.4
-Build-Depends: debhelper (>> 7.1), zlib1g-dev, libjpeg-turbo8-dev, libxaw7-dev (>> 4.1.0), perl-modules, xfonts-base, xutils-dev, libx11-dev, libxau-dev, libxext-dev, libxi-dev, libxkbfile-dev, libxmu-dev, libxt-dev, x11proto-core-dev, cmake (>> 2.8), libgnutls28-dev, libpam0g-dev, libpng-dev, automake, autoconf, libtool, pkg-config, libpixman-1-dev, x11proto-bigreqs-dev, x11proto-composite-dev, x11proto-damage-dev, x11proto-dri2-dev, x11proto-fixes-dev, x11proto-fonts-dev, x11proto-gl-dev, x11proto-input-dev, x11proto-kb-dev, x11proto-randr-dev, x11proto-render-dev, x11proto-resource-dev, x11proto-scrnsaver-dev, x11proto-video-dev, x11proto-xext-dev, x11proto-xf86bigfont-dev, x11proto-xf86dga-dev, x11proto-xf86dri-dev, x11proto-xf86vidmode-dev, x11proto-xinerama-dev, libosmesa6-dev, libgl1-mesa-dev, libgl1-mesa-dri, libgl1-mesa-glx, libxfont-dev, x11proto-record-dev, default-jdk, libxtst-dev, libxft-dev, libexpat1-dev, libfontconfig1-dev, libxrender-dev, libt1-dev, libpciaccess-dev, curl, bzip2, quilt, libglu1-mesa-dev, libxcursor-dev, libxinerama-dev, libxfixes-dev, libcairo2-dev, x11proto-dri3-dev, libgcrypt20-dev, x11proto-xcmisc-dev, x11proto-present-dev
+Build-Depends: debhelper (>> 7.1), zlib1g-dev, libjpeg-turbo8-dev, libxaw7-dev (>> 4.1.0), perl-modules, xfonts-base, xutils-dev, libx11-dev, libxau-dev, libxext-dev, libxi-dev, libxkbfile-dev, libxmu-dev, libxt-dev, x11proto-core-dev, cmake (>> 2.8), libgnutls28-dev, libpam0g-dev, libpng-dev, automake, autoconf, libtool, pkg-config, libpixman-1-dev, x11proto-bigreqs-dev, x11proto-composite-dev, x11proto-damage-dev, x11proto-dri2-dev, x11proto-fixes-dev, x11proto-fonts-dev, x11proto-gl-dev, x11proto-input-dev, x11proto-kb-dev, x11proto-randr-dev, x11proto-render-dev, x11proto-resource-dev, x11proto-scrnsaver-dev, x11proto-video-dev, x11proto-xext-dev, x11proto-xf86bigfont-dev, x11proto-xf86dga-dev, x11proto-xf86dri-dev, x11proto-xf86vidmode-dev, x11proto-xinerama-dev, libosmesa6-dev, libgl1-mesa-dev, libgl1-mesa-dri, libgl1-mesa-glx, libxfont-dev, x11proto-record-dev, default-jdk, libxtst-dev, libxft-dev, libexpat1-dev, libfontconfig1-dev, libxrender-dev, libt1-dev, libpciaccess-dev, curl, bzip2, quilt, libglu1-mesa-dev, libxcursor-dev, libxinerama-dev, libxfixes-dev, libcairo2-dev, x11proto-dri3-dev, libgcrypt20-dev, x11proto-xcmisc-dev, x11proto-present-dev, libtasn1-dev
Homepage: http://www.tigervnc.com
Package: tigervncserver
Architecture: any
Provides: xserver, vnc-server
-Depends: x11-common | xserver-common, x11-utils, xauth, libbz2-1.0, libc6, libfontenc1, libfreetype6, libgcc1, libgl1-mesa-dri, libgnutls28, libjpeg-turbo8, libp11-kit0, libpam0g, libpixman-1-0, libstdc++6, libtasn1-3-bin, libx11-6, libxau6, libxcb1, libxdmcp6, libxext6, libxfont1, libxtst6, zlib1g, libglu1-mesa, libxcursor1, libxinerama1, libxfixes3, x11-xkb-utils, libgcrypt20
+Depends: x11-common | xserver-common, x11-utils, xauth, libbz2-1.0, libc6, libfontenc1, libfreetype6, libgcc1, libgl1-mesa-dri, libgnutls28, libjpeg-turbo8, libp11-kit0, libpam0g, libpixman-1-0, libstdc++6, libtasn1-bin, libx11-6, libxau6, libxcb1, libxdmcp6, libxext6, libxfont1, libxtst6, zlib1g, libglu1-mesa, libxcursor1, libxinerama1, libxfixes3, x11-xkb-utils, libgcrypt20
Recommends: xfonts-base, x11-xserver-utils
Suggests: xtigervncviewer, tigervnc-java
Description: virtual network computing server software
@@ -30,7 +30,7 @@
Package: xtigervncviewer
Architecture: any
Provides: vncviewer, vnc-viewer
-Depends: libc6, libexpat1, libfontconfig1, libfreetype6, libgcc1, libgnutls28, libjpeg-turbo8, libp11-kit0, libpng12-0, libstdc++6, libtasn1-3-bin, libx11-6, libxau6, libxcb1, libxdmcp6, libxext6, libxft2, libxrender1, zlib1g, libglu1-mesa, libxcursor1, libxinerama1, libxfixes3
+Depends: libc6, libexpat1, libfontconfig1, libfreetype6, libgcc1, libgnutls28, libjpeg-turbo8, libp11-kit0, libpng12-0, libstdc++6, libtasn1-bin, libx11-6, libxau6, libxcb1, libxdmcp6, libxext6, libxft2, libxrender1, zlib1g, libglu1-mesa, libxcursor1, libxinerama1, libxfixes3
Recommends: xfonts-base
Suggests: tigervncserver, ssh
Description: virtual network computing client software for X
diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt
index 7d6c70a..82de6c0 100644
--- a/java/CMakeLists.txt
+++ b/java/CMakeLists.txt
@@ -126,15 +126,18 @@
if(NOT "${SRCDIR}" STREQUAL "${BINDIR}")
-add_custom_command(OUTPUT ${BINDIR}/${CLASSPATH}/tigervnc.png
- COMMAND ${CMAKE_COMMAND} -E copy_if_different
- ${SRCDIR}/${CLASSPATH}/tigervnc.png ${BINDIR}/${CLASSPATH}/tigervnc.png
- DEPENDS ${SRCDIR}/${CLASSPATH}/tigervnc.png)
+set(ICONS
+tigervnc.ico
+tigervnc.png
+insecure.png
+secure.png)
-add_custom_command(OUTPUT ${BINDIR}/${CLASSPATH}/tigervnc.ico
- COMMAND ${CMAKE_COMMAND} -E copy_if_different
- ${SRCDIR}/${CLASSPATH}/tigervnc.ico ${BINDIR}/${CLASSPATH}/tigervnc.ico
- DEPENDS ${SRCDIR}/${CLASSPATH}/tigervnc.ico)
+foreach(icon ${ICONS})
+ add_custom_command(OUTPUT ${BINDIR}/${CLASSPATH}/${icon}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${SRCDIR}/${CLASSPATH}/${icon} ${BINDIR}/${CLASSPATH}/${icon}
+ DEPENDS ${SRCDIR}/${CLASSPATH}/${icon})
+endforeach()
endif()
@@ -145,8 +148,10 @@
DEPENDS ${JAVA_CLASSES}
${SRCDIR}/${CLASSPATH}/MANIFEST.MF
${BINDIR}/${CLASSPATH}/timestamp
- ${BINDIR}/${CLASSPATH}/tigervnc.png
${BINDIR}/${CLASSPATH}/tigervnc.ico
+ ${BINDIR}/${CLASSPATH}/tigervnc.png
+ ${BINDIR}/${CLASSPATH}/insecure.png
+ ${BINDIR}/${CLASSPATH}/secure.png
COMMAND ${JAVA_ARCHIVE}
ARGS cfm VncViewer.jar
${SRCDIR}/${CLASSPATH}/MANIFEST.MF
@@ -159,7 +164,7 @@
com/jcraft/jsch/jcraft/*.class
com/jcraft/jsch/jce/*.class
com/jcraft/jsch/*.class
- com/tigervnc/vncviewer/tigervnc.png
+ com/tigervnc/vncviewer/*.png
com/tigervnc/vncviewer/tigervnc.ico
COMMAND ${CMAKE_COMMAND}
ARGS -DJava_PATH=${Java_PATH} -DJAR_FILE=${BINDIR}/VncViewer.jar
diff --git a/java/com/tigervnc/rfb/CConnection.java b/java/com/tigervnc/rfb/CConnection.java
index aefc276..c9b6b89 100644
--- a/java/com/tigervnc/rfb/CConnection.java
+++ b/java/com/tigervnc/rfb/CConnection.java
@@ -389,6 +389,8 @@
// Identities, to determine the unique(ish) name of the server.
public String getServerName() { return serverName; }
+ public boolean isSecure() { return csecurity != null ? csecurity.isSecure() : false; }
+
public static final int RFBSTATE_UNINITIALISED = 0;
public static final int RFBSTATE_PROTOCOL_VERSION = 1;
public static final int RFBSTATE_SECURITY_TYPES = 2;
diff --git a/java/com/tigervnc/rfb/CSecurity.java b/java/com/tigervnc/rfb/CSecurity.java
index f67680c..f192d30 100644
--- a/java/com/tigervnc/rfb/CSecurity.java
+++ b/java/com/tigervnc/rfb/CSecurity.java
@@ -37,10 +37,11 @@
abstract public boolean processMsg(CConnection cc);
abstract public int getType();
abstract public String description();
+ public boolean isSecure() { return false; }
/*
* Use variable directly instead of dumb get/set methods.
* It MUST be set by viewer.
*/
- static UserPasswdGetter upg;
+ public static UserPasswdGetter upg;
}
diff --git a/java/com/tigervnc/rfb/CSecurityIdent.java b/java/com/tigervnc/rfb/CSecurityIdent.java
index 9eb6e0b..872b84a 100644
--- a/java/com/tigervnc/rfb/CSecurityIdent.java
+++ b/java/com/tigervnc/rfb/CSecurityIdent.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Brian P. Hinz
+/* Copyright (C) 2011-2017 Brian P. Hinz
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
StringBuffer username = new StringBuffer();
- CConn.upg.getUserPasswd(username, null);
+ upg.getUserPasswd(cc.isSecure(), username, null);
// Return the response to the server
os.writeU32(username.length());
@@ -46,9 +46,6 @@
public int getType() { return Security.secTypeIdent; }
- java.net.Socket sock;
- UserPasswdGetter upg;
-
static LogWriter vlog = new LogWriter("Ident");
public String description() { return "No Encryption"; }
diff --git a/java/com/tigervnc/rfb/CSecurityPlain.java b/java/com/tigervnc/rfb/CSecurityPlain.java
index d6f8ffd..ef7a10e 100644
--- a/java/com/tigervnc/rfb/CSecurityPlain.java
+++ b/java/com/tigervnc/rfb/CSecurityPlain.java
@@ -1,6 +1,6 @@
/* Copyright (C) 2005 Martin Koegler
* Copyright (C) 2010 TigerVNC Team
- * Copyright (C) 2011 Brian P. Hinz
+ * Copyright (C) 2011-2017 Brian P. Hinz
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
StringBuffer username = new StringBuffer();
StringBuffer password = new StringBuffer();
- CConn.upg.getUserPasswd(username, password);
+ upg.getUserPasswd(cc.isSecure(), username, password);
// Return the response to the server
os.writeU32(username.length());
diff --git a/java/com/tigervnc/rfb/CSecurityStack.java b/java/com/tigervnc/rfb/CSecurityStack.java
index e4f5988..31e21f7 100644
--- a/java/com/tigervnc/rfb/CSecurityStack.java
+++ b/java/com/tigervnc/rfb/CSecurityStack.java
@@ -59,6 +59,15 @@
return res;
}
+ public boolean isSecure()
+ {
+ if (state0 != null && state0.isSecure())
+ return true;
+ if (state == 1 && state1 != null && state1.isSecure())
+ return true;
+ return false;
+ }
+
public final int getType() { return type; }
public final String description() { return name; }
diff --git a/java/com/tigervnc/rfb/CSecurityTLS.java b/java/com/tigervnc/rfb/CSecurityTLS.java
index 733e97d..e07ab9b 100644
--- a/java/com/tigervnc/rfb/CSecurityTLS.java
+++ b/java/com/tigervnc/rfb/CSecurityTLS.java
@@ -56,6 +56,8 @@
import com.tigervnc.network.*;
import com.tigervnc.vncviewer.*;
+import static javax.swing.JOptionPane.*;
+
public class CSecurityTLS extends CSecurity {
public static StringParameter X509CA
@@ -64,6 +66,7 @@
public static StringParameter X509CRL
= new StringParameter("X509CRL",
"X509 CRL file", "", Configuration.ConfigurationObject.ConfViewer);
+ public static UserMsgBox msg;
private void initGlobal()
{
@@ -254,6 +257,16 @@
{
Collection<? extends Certificate> certs = null;
X509Certificate cert = chain[0];
+ try {
+ cert.checkValidity();
+ } catch(CertificateNotYetValidException e) {
+ throw new AuthFailureException("server certificate has not been activated");
+ } catch(CertificateExpiredException e) {
+ if (!msg.showMsgBox(YES_NO_OPTION, "certificate has expired",
+ "The certificate of the server has expired, "+
+ "do you want to continue?"))
+ throw new AuthFailureException("server certificate has expired");
+ }
String thumbprint = getThumbprint(cert);
File vncDir = new File(FileUtils.getVncHomeDir());
File certFile = new File(vncDir, "x509_savedcerts.pem");
@@ -270,8 +283,7 @@
tm.checkServerTrusted(chain, authType);
} catch (java.lang.Exception e) {
if (e.getCause() instanceof CertPathBuilderException) {
- Object[] answer = {"YES", "NO"};
- int ret = JOptionPane.showOptionDialog(null,
+ String certinfo =
"This certificate has been signed by an unknown authority\n"+
"\n"+
" Subject: "+cert.getSubjectX500Principal().getName()+"\n"+
@@ -283,46 +295,38 @@
" Not Valid After: "+cert.getNotAfter()+"\n"+
" SHA1 Fingerprint: "+getThumbprint(cert)+"\n"+
"\n"+
- "Do you want to save it and continue?",
- "Certificate Issuer Unknown",
- JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
- null, answer, answer[0]);
- if (ret == JOptionPane.YES_OPTION) {
+ "Do you want to save it and continue?";
+ if (!msg.showMsgBox(YES_NO_OPTION, "certificate issuer unknown",
+ certinfo)) {
+ throw new AuthFailureException("certificate issuer unknown");
+ }
+ if (certs == null || !certs.contains(cert)) {
+ byte[] der = cert.getEncoded();
+ String pem = DatatypeConverter.printBase64Binary(der);
+ pem = pem.replaceAll("(.{64})", "$1\n");
+ FileWriter fw = null;
try {
if (!vncDir.exists())
vncDir.mkdir();
if (!certFile.exists() && !certFile.createNewFile()) {
vlog.error("Certificate save failed.");
- return;
- }
- } catch (java.lang.Exception ioe) {
- // skip save if security settings prohibit access to filesystem
- vlog.error("Certificate save failed: "+ioe.getMessage());
- return;
- }
- if (certs == null || !certs.contains(cert)) {
- byte[] der = cert.getEncoded();
- String pem = DatatypeConverter.printBase64Binary(der);
- pem = pem.replaceAll("(.{64})", "$1\n");
- FileWriter fw = null;
- try {
+ } else {
fw = new FileWriter(certFile.getAbsolutePath(), true);
fw.write("-----BEGIN CERTIFICATE-----\n");
fw.write(pem+"\n");
fw.write("-----END CERTIFICATE-----\n");
- } catch (IOException ioe) {
- throw new Exception(ioe.getMessage());
- } finally {
- try {
- if (fw != null)
- fw.close();
- } catch(IOException ioe2) {
- throw new Exception(ioe2.getMessage());
- }
+ }
+ } catch (IOException ioe) {
+ msg.showMsgBox(OK_OPTION, "certificate save failed",
+ "Could not save the certificate");
+ } finally {
+ try {
+ if (fw != null)
+ fw.close();
+ } catch(IOException ioe2) {
+ throw new Exception(ioe2.getMessage());
}
}
- } else {
- throw new WarningException("Peer certificate verification failed.");
}
} else {
throw new SystemException(e.getMessage());
@@ -458,6 +462,7 @@
public final int getType() { return anon ? Security.secTypeTLSNone : Security.secTypeX509None; }
public final String description()
{ return anon ? "TLS Encryption without VncAuth" : "X509 Encryption without VncAuth"; }
+ public boolean isSecure() { return !anon; }
protected CConnection client;
diff --git a/java/com/tigervnc/rfb/CSecurityVeNCrypt.java b/java/com/tigervnc/rfb/CSecurityVeNCrypt.java
index 179900a..8bffedf 100644
--- a/java/com/tigervnc/rfb/CSecurityVeNCrypt.java
+++ b/java/com/tigervnc/rfb/CSecurityVeNCrypt.java
@@ -178,7 +178,19 @@
}
public final int getType() { return chosenType; }
- public final String description() { return Security.secTypeName(chosenType); }
+ public final String description()
+ {
+ if (csecurity != null)
+ return csecurity.description();
+ return "VeNCrypt";
+ }
+
+ public final boolean isSecure()
+ {
+ if (csecurity != null && csecurity.isSecure())
+ return true;
+ return false;
+ }
public static StringParameter secTypesStr;
diff --git a/java/com/tigervnc/rfb/CSecurityVncAuth.java b/java/com/tigervnc/rfb/CSecurityVncAuth.java
index e053e41..0615495 100644
--- a/java/com/tigervnc/rfb/CSecurityVncAuth.java
+++ b/java/com/tigervnc/rfb/CSecurityVncAuth.java
@@ -36,7 +36,7 @@
byte[] challenge = new byte[vncAuthChallengeSize];
is.readBytes(challenge, 0, vncAuthChallengeSize);
StringBuffer passwd = new StringBuffer();
- CConn.upg.getUserPasswd(null, passwd);
+ upg.getUserPasswd(cc.isSecure(), null, passwd);
// Calculate the correct response
byte[] key = new byte[8];
diff --git a/java/com/tigervnc/rfb/SecurityClient.java b/java/com/tigervnc/rfb/SecurityClient.java
index ff2433c..d355733 100644
--- a/java/com/tigervnc/rfb/SecurityClient.java
+++ b/java/com/tigervnc/rfb/SecurityClient.java
@@ -1,6 +1,6 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2010 TigerVNC Team
- * Copyright (C) 2011-2012 Brian P. Hinz
+ * Copyright (C) 2011-2017 Brian P. Hinz
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,16 +20,14 @@
package com.tigervnc.rfb;
-import com.tigervnc.vncviewer.CConn;
-
public class SecurityClient extends Security {
public SecurityClient() { super(secTypes); }
public CSecurity GetCSecurity(int secType)
{
- assert (CConn.upg != null); /* (upg == null) means bug in the viewer */
- assert (msg != null);
+ assert (CSecurity.upg != null); /* (upg == null) means bug in the viewer */
+ assert (CSecurityTLS.msg != null);
if (!IsSupported(secType))
throw new Exception("Security type not supported");
@@ -75,9 +73,6 @@
CSecurityTLS.setDefaults();
}
- //UserPasswdGetter upg = null;
- String msg = null;
-
public static StringParameter secTypes
= new StringParameter("SecurityTypes",
"Specify which security scheme to use (None, VncAuth, Plain, Ident, TLSNone, TLSVnc, TLSPlain, TLSIdent, X509None, X509Vnc, X509Plain, X509Ident)",
diff --git a/java/com/tigervnc/rfb/UserPasswdGetter.java b/java/com/tigervnc/rfb/UserPasswdGetter.java
index feb05ed..457eaf2 100644
--- a/java/com/tigervnc/rfb/UserPasswdGetter.java
+++ b/java/com/tigervnc/rfb/UserPasswdGetter.java
@@ -23,5 +23,5 @@
package com.tigervnc.rfb;
public interface UserPasswdGetter {
- public boolean getUserPasswd(StringBuffer user, StringBuffer password);
+ public void getUserPasswd(boolean secure, StringBuffer user, StringBuffer password);
}
diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java
index d71c307..3aee46d 100644
--- a/java/com/tigervnc/vncviewer/CConn.java
+++ b/java/com/tigervnc/vncviewer/CConn.java
@@ -63,7 +63,7 @@
import static com.tigervnc.vncviewer.Parameters.*;
public class CConn extends CConnection implements
- UserPasswdGetter, FdInStreamBlockCallback, ActionListener {
+ FdInStreamBlockCallback, ActionListener {
// 8 colours (1 bit per component)
static final PixelFormat verylowColorPF =
@@ -92,8 +92,6 @@
setShared(shared.getValue());
sock = socket;
- upg = this;
-
int encNum = Encodings.encodingNum(preferredEncoding.getValue());
if (encNum != -1)
currentEncoding = encNum;
@@ -208,58 +206,6 @@
}
}
- // getUserPasswd() is called by the CSecurity object when it needs us to read
- // a password from the user.
-
- public final boolean getUserPasswd(StringBuffer user, StringBuffer passwd) {
- String title = ("VNC Authentication ["
- +csecurity.description() + "]");
- String passwordFileStr = passwordFile.getValue();
- PasswdDialog dlg;
-
- if (user == null && !passwordFileStr.equals("")) {
- InputStream fp = null;
- try {
- fp = new FileInputStream(passwordFileStr);
- } catch(FileNotFoundException e) {
- throw new Exception("Opening password file failed");
- }
- byte[] obfPwd = new byte[256];
- try {
- fp.read(obfPwd);
- fp.close();
- } catch(IOException e) {
- throw new Exception("Failed to read VncPasswd file");
- }
- String PlainPasswd = VncAuth.unobfuscatePasswd(obfPwd);
- passwd.append(PlainPasswd);
- passwd.setLength(PlainPasswd.length());
- return true;
- }
-
- if (user == null) {
- dlg = new PasswdDialog(title, (user == null), (passwd == null));
- } else {
- if ((passwd == null) && sendLocalUsername.getValue()) {
- user.append((String)System.getProperties().get("user.name"));
- return true;
- }
- dlg = new PasswdDialog(title, sendLocalUsername.getValue(),
- (passwd == null));
- }
- dlg.showDialog();
- if (user != null) {
- if (sendLocalUsername.getValue()) {
- user.append((String)System.getProperties().get("user.name"));
- } else {
- user.append(dlg.userEntry.getText());
- }
- }
- if (passwd != null)
- passwd.append(new String(dlg.passwdEntry.getPassword()));
- return true;
- }
-
////////////////////// CConnection callback methods //////////////////////
// serverInit() is called when the serverInit message has been received. At
@@ -729,8 +675,6 @@
// the following need no synchronization:
- public static UserPasswdGetter upg;
-
// shuttingDown is set by the GUI thread and only ever tested by the RFB
// thread after the window has been destroyed.
boolean shuttingDown = false;
diff --git a/java/com/tigervnc/vncviewer/UserDialog.java b/java/com/tigervnc/vncviewer/UserDialog.java
new file mode 100644
index 0000000..dfced98
--- /dev/null
+++ b/java/com/tigervnc/vncviewer/UserDialog.java
@@ -0,0 +1,208 @@
+/* Copyright (C) 2017 Brian P. Hinz
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+package com.tigervnc.vncviewer;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import javax.swing.plaf.LayerUI;
+
+import com.tigervnc.rfb.*;
+import com.tigervnc.rfb.Point;
+import com.tigervnc.rfb.Exception;
+
+import static com.tigervnc.vncviewer.Parameters.*;
+import static javax.swing.GroupLayout.*;
+import static javax.swing.JOptionPane.*;
+
+
+public class UserDialog implements UserPasswdGetter, UserMsgBox
+{
+ private class MyLayerUI extends LayerUI {
+ // Using a JButton for the "?" icon yields the best look, but there
+ // does not seem to be any reasonable way to disable a JButton without
+ // also changing the color. This wrapper just intercepts any mouse
+ // click events so that the button just looks like an icon.
+ @Override
+ public void eventDispatched(AWTEvent e, JLayer l) {
+ if (e instanceof InputEvent)
+ ((InputEvent) e).consume();
+ }
+
+ @Override
+ public void installUI(JComponent c) {
+ super.installUI(c);
+ if (c instanceof JLayer) {
+ JLayer<?> layer = (JLayer<?>)c;
+ layer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
+ }
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e, JLayer l) {
+ super.processMouseEvent(e, l);
+ }
+ }
+
+ public final void getUserPasswd(boolean secure, StringBuffer user, StringBuffer password)
+ {
+ String passwordFileStr = passwordFile.getValue();
+
+ if ((password == null) && sendLocalUsername.getValue()) {
+ user.append((String)System.getProperties().get("user.name"));
+ return;
+ }
+
+ if (user == null && !passwordFileStr.equals("")) {
+ InputStream fp = null;
+ try {
+ fp = new FileInputStream(passwordFileStr);
+ } catch(FileNotFoundException e) {
+ throw new Exception("Opening password file failed");
+ }
+ byte[] obfPwd = new byte[256];
+ try {
+ fp.read(obfPwd);
+ fp.close();
+ } catch(IOException e) {
+ throw new Exception("Failed to read VncPasswd file");
+ }
+ String PlainPasswd = VncAuth.unobfuscatePasswd(obfPwd);
+ password.append(PlainPasswd);
+ password.setLength(PlainPasswd.length());
+ return;
+ }
+
+ JDialog win;
+ JLabel banner;
+ JTextField username = null;
+ JPasswordField passwd = null;
+ JLayer icon;
+
+ int y;
+
+ JPanel msg = new JPanel(null);
+ msg.setSize(410, 145);
+
+ banner = new JLabel();
+ banner.setBounds(0, 0, msg.getPreferredSize().width, 20);
+ banner.setHorizontalAlignment(JLabel.CENTER);
+ banner.setOpaque(true);
+
+ if (secure) {
+ banner.setText("This connection is secure");
+ banner.setBackground(Color.GREEN);
+ ImageIcon secure_icon =
+ new ImageIcon(VncViewer.class.getResource("secure.png"));
+ banner.setIcon(secure_icon);
+ } else {
+ banner.setText("This connection is not secure");
+ banner.setBackground(Color.RED);
+ ImageIcon insecure_icon =
+ new ImageIcon(VncViewer.class.getResource("insecure.png"));
+ banner.setIcon(insecure_icon);
+ }
+ msg.add(banner);
+
+ y = 20 + 10;
+
+ JButton iconb = new JButton("?");
+ iconb.setVerticalAlignment(JLabel.CENTER);
+ iconb.setFont(new Font("Times", Font.BOLD, 34));
+ iconb.setForeground(Color.BLUE);
+ LayerUI ui = new MyLayerUI();
+ icon = new JLayer(iconb, ui);
+ icon.setBounds(10, y, 50, 50);
+ msg.add(icon);
+
+ y += 5;
+
+ if (user != null && !sendLocalUsername.getValue()) {
+ JLabel userLabel = new JLabel("Username:");
+ userLabel.setBounds(70, y, msg.getSize().width-70-10, 20);
+ msg.add(userLabel);
+ y += 20 + 5;
+ username = new JTextField(30);
+ username.setBounds(70, y, msg.getSize().width-70-10, 25);
+ msg.add(username);
+ y += 25 + 5;
+ }
+
+ JLabel passwdLabel = new JLabel("Password:");
+ passwdLabel.setBounds(70, y, msg.getSize().width-70-10, 20);
+ msg.add(passwdLabel);
+ y += 20 + 5;
+ passwd = new JPasswordField(30);
+ passwd.setBounds(70, y, msg.getSize().width-70-10, 25);
+ msg.add(passwd);
+ y += 25 + 5;
+
+ msg.setPreferredSize(new Dimension(410, y));
+
+ Object[] options = {"OK \u21B5", "Cancel"};
+ JOptionPane pane = new JOptionPane(msg,
+ PLAIN_MESSAGE,
+ OK_CANCEL_OPTION,
+ null, //do not use a custom Icon
+ options, //the titles of buttons
+ options[0]);//default button title
+ pane.setBorder(new EmptyBorder(0,0,0,0));
+ Component c = pane.getComponent(pane.getComponentCount()-1);
+ ((JComponent)c).setBorder(new EmptyBorder(0,0,10,10));
+ win = pane.createDialog("VNC Authentication");
+
+ win.setVisible(true);
+
+ if (pane.getValue() == null || pane.getValue().equals("Cancel"))
+ throw new Exception("Authentication cancelled");
+
+ if (user != null)
+ if (sendLocalUsername.getValue())
+ user.append((String)System.getProperties().get("user.name"));
+ else
+ user.append(username.getText());
+ if (password != null)
+ password.append(new String(passwd.getPassword()));
+ }
+
+ public boolean showMsgBox(int flags, String title, String text)
+ {
+ switch (flags & 0xf) {
+ case OK_CANCEL_OPTION:
+ return (showConfirmDialog(null, text, title, OK_CANCEL_OPTION) == OK_OPTION);
+ case YES_NO_OPTION:
+ return (showConfirmDialog(null, text, title, YES_NO_OPTION) == YES_OPTION);
+ default:
+ if (((flags & 0xf0) == ERROR_MESSAGE) ||
+ ((flags & 0xf0) == WARNING_MESSAGE))
+ showMessageDialog(null, text, title, (flags & 0xf0));
+ else
+ showMessageDialog(null, text, title, PLAIN_MESSAGE);
+ return true;
+ }
+ }
+}
diff --git a/java/com/tigervnc/vncviewer/VncViewer.java b/java/com/tigervnc/vncviewer/VncViewer.java
index 8786c11..74f2ca3 100644
--- a/java/com/tigervnc/vncviewer/VncViewer.java
+++ b/java/com/tigervnc/vncviewer/VncViewer.java
@@ -486,6 +486,9 @@
public void run() {
cc = null;
+ UserDialog dlg = new UserDialog();
+ CSecurity.upg = dlg;
+ CSecurityTLS.msg = dlg;
Socket sock = null;
/* Specifying -via and -listen together is nonsense */
diff --git a/java/com/tigervnc/vncviewer/insecure.png b/java/com/tigervnc/vncviewer/insecure.png
new file mode 100644
index 0000000..f48faff
--- /dev/null
+++ b/java/com/tigervnc/vncviewer/insecure.png
Binary files differ
diff --git a/java/com/tigervnc/vncviewer/secure.png b/java/com/tigervnc/vncviewer/secure.png
new file mode 100644
index 0000000..9383371
--- /dev/null
+++ b/java/com/tigervnc/vncviewer/secure.png
Binary files differ
diff --git a/media/insecure.xpm b/media/insecure.xpm
index f5053fe..e42ee14 100644
--- a/media/insecure.xpm
+++ b/media/insecure.xpm
@@ -1,71 +1,44 @@
/* XPM */
static char *insecure[] = {
/* columns rows colors chars-per-pixel */
-"15 15 50 1 ",
-" c black",
-". c #020000",
-"X c #050000",
-"o c #080000",
-"O c #0A0000",
-"+ c #0C0000",
-"@ c #0D0000",
-"# c #0F0000",
-"$ c #100000",
-"% c #110000",
-"& c #120000",
-"* c #140000",
-"= c #290000",
-"- c #330000",
-"; c #370000",
-": c #430000",
-"> c #560000",
-", c #620000",
-"< c #660000",
-"1 c #6C0000",
-"2 c #7D0000",
-"3 c #800000",
-"4 c #810000",
-"5 c #840000",
-"6 c #870000",
-"7 c #950000",
-"8 c #A20000",
-"9 c #AB0000",
-"0 c #B30000",
-"q c #B40000",
-"w c #C00000",
-"e c #C40000",
-"r c #CD0000",
-"t c #DC0000",
-"y c #DD0000",
-"u c #DF0000",
-"i c #E40000",
-"p c #E50000",
-"a c #E60000",
-"s c #EA0000",
-"d c #EB0000",
-"f c #ED0000",
-"g c #F00000",
-"h c #F40000",
-"j c #F90000",
-"k c #FA0000",
-"l c #FB0000",
-"z c #FC0000",
-"x c #FD0000",
-"c c red",
+"16 16 22 1 ",
+" c #000000",
+". c #040000",
+"X c #0D0000",
+"o c #120000",
+"O c #3A0000",
+"+ c #3D0000",
+"@ c #4B0000",
+"# c #530000",
+"$ c #5B0000",
+"% c #770000",
+"& c #810000",
+"* c #8E0000",
+"= c #940000",
+"- c #980000",
+"; c #AB0000",
+": c #BB0000",
+"> c #C00000",
+", c #DC0000",
+"< c #E30000",
+"1 c #E40000",
+"2 c #FC0000",
+"3 c #FF0000",
/* pixels */
-"ccccccccccccccc",
-"ccccccjpkcr:fcc",
-"ccccz6+ @1$ rcc",
-"cccc2 O-o wccc",
-"cccdX%tr# 4cccc",
-"ccce >r& 7czccc",
-"ccq< =O 8cg60cc",
-"cs. 3cg; ac",
-"cu 3cg; uc",
-"cu 3cg; uc",
-"c0 3cg; uc",
-"r$ 3cg; uc",
-", 5cg; *hc",
-"l9lxiyyyyyyyhcc",
-"ccccccccccccccc"
+"3333333333333333",
+"33333333333;%333",
+"33333<#XX#*. ,33",
+"3333<o :333",
+"3333# @1- =3333",
+"3333X <;. %33333",
+"3333 ;. :333333",
+"33O &33$ O33",
+"33 %33$ 33",
+"33 &33$ 33",
+"33 &33$ 33",
+"3; &33$ 33",
+";. &33$ 33",
+"& *33$ +33",
+"3>33333333333333",
+"3333333333333333"
};
diff --git a/media/secure.xpm b/media/secure.xpm
index 49a3791..8d89548 100644
--- a/media/secure.xpm
+++ b/media/secure.xpm
@@ -1,56 +1,34 @@
/* XPM */
static char *secure[] = {
/* columns rows colors chars-per-pixel */
-"15 15 35 1 ",
-" c black",
-". c #000200",
-"X c #000500",
-"o c #000A00",
-"O c #000C00",
-"+ c #000D00",
-"@ c #001000",
-"# c #001100",
-"$ c #001400",
-"% c #003300",
-"& c #005500",
-"* c #005600",
-"= c #006600",
-"- c #007D00",
-"; c #007E00",
-": c #008700",
-"> c #008800",
-", c #00B300",
-"< c #00B400",
-"1 c #00C400",
-"2 c #00DB00",
-"3 c #00DC00",
-"4 c #00DD00",
-"5 c #00DF00",
-"6 c #00E500",
-"7 c #00E600",
-"8 c #00EA00",
-"9 c #00EB00",
-"0 c #00ED00",
-"q c #00F000",
-"w c #00F400",
-"e c #00F900",
-"r c #00FA00",
-"t c #00FC00",
-"y c green",
+"16 16 12 1 ",
+" c #000000",
+". c #000D00",
+"X c #001200",
+"o c #003A00",
+"O c #003C00",
+"+ c #004B00",
+"@ c #005300",
+"# c #005500",
+"$ c #00D800",
+"% c #00E300",
+"& c #00E400",
+"* c #00FF00",
/* pixels */
-"yyyyyyyyyyyyyyy",
-"yyyyyye6ryyyyyy",
-"yyyyt:O +>tyyyy",
-"yyyy- o%o ;yyyy",
-"yyy9X#3y2@X0yyy",
-"yyy1 *yyy& 1yyy",
-"yy<= %>>>% =,yy",
-"y8. 7y",
-"y5 5y",
-"y5 5y",
-"y5 5y",
-"y5 5y",
-"yw# $wy",
-"yyq444444444wyy",
-"yyyyyyyyyyyyyyy"
+"****************",
+"****************",
+"*****%@..@$*****",
+"****%X .%****",
+"****@ +&%+ #****",
+"****. %**% .****",
+"**** **** ****",
+"**o O**",
+"** **",
+"** **",
+"** **",
+"** **",
+"** **",
+"**O O**",
+"****************",
+"****************"
};