* Use variable directly instead of dumb get/set methods.
* It MUST be set by viewer.
*/
- static UserPasswdGetter upg;
+ public static UserPasswdGetter upg;
}
-/* 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
StringBuffer username = new StringBuffer();
- CConn.upg.getUserPasswd(username, null);
+ upg.getUserPasswd(username, null);
// Return the response to the server
os.writeU32(username.length());
public int getType() { return Security.secTypeIdent; }
- java.net.Socket sock;
- UserPasswdGetter upg;
-
static LogWriter vlog = new LogWriter("Ident");
public String description() { return "No Encryption"; }
/* 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
StringBuffer username = new StringBuffer();
StringBuffer password = new StringBuffer();
- CConn.upg.getUserPasswd(username, password);
+ upg.getUserPasswd(username, password);
// Return the response to the server
os.writeU32(username.length());
import com.tigervnc.network.*;
import com.tigervnc.vncviewer.*;
+import static javax.swing.JOptionPane.*;
+
public class CSecurityTLS extends CSecurity {
public static StringParameter X509CA
public static StringParameter X509CRL
= new StringParameter("X509CRL",
"X509 CRL file", "", Configuration.ConfigurationObject.ConfViewer);
+ public static UserMsgBox msg;
private void initGlobal()
{
{
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");
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"+
" 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());
}
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 static StringParameter secTypesStr;
byte[] challenge = new byte[vncAuthChallengeSize];
is.readBytes(challenge, 0, vncAuthChallengeSize);
StringBuffer passwd = new StringBuffer();
- CConn.upg.getUserPasswd(null, passwd);
+ upg.getUserPasswd(null, passwd);
// Calculate the correct response
byte[] key = new byte[8];
/* 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
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");
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)",
package com.tigervnc.rfb;
public interface UserPasswdGetter {
- public boolean getUserPasswd(StringBuffer user, StringBuffer password);
+ public void getUserPasswd(StringBuffer user, StringBuffer password);
}
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 =
setShared(shared.getValue());
sock = socket;
- upg = this;
-
int encNum = Encodings.encodingNum(preferredEncoding.getValue());
if (encNum != -1)
currentEncoding = encNum;
}
}
- // 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
// 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;
--- /dev/null
+/* 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(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;
+ JTextField username = null;
+ JPasswordField passwd = null;
+ JLayer icon;
+
+ int y;
+
+ JPanel msg = new JPanel(null);
+ msg.setSize(410, 145);
+
+ y = 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;
+ }
+ }
+}
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 */