package cologne.eck.all_peas.gui;
/*
* Peafactory - Production of Password Encryption Archives
* Copyright (C) 2015 Axel von dem Bruch
*
* This library 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 library 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.
* See: http://www.gnu.org/licenses/gpl-2.0.html
* You should have received a copy of the GNU General Public License
* along with this library.
*/
/**
* Dialog to change the password of the pea.
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.ResourceBundle;
import javax.accessibility.AccessibleContext;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import cologne.eck.all_peas.data.PeaProperties;
import cologne.eck.tools.KeyRandomCollector;
import cologne.eck.tools.MouseRandomCollector;
import cologne.eck.tools.PasswordQualityCheck;
import cologne.eck.tools.Zeroizer;
public class NewPasswordDialog extends JDialog implements ActionListener, DocumentListener {//KeyListener {
private static final long serialVersionUID = 1L;
private static NewPasswordDialog newPswDialog = null;
private static JLabel messageLabel = null;
private static JPasswordField newPasswordField;
private static JLabel qualityLabel;
private static JLabel qualityLabelStars;
private static JPasswordField retypePasswordField;
private JLabel hintLabel;
private static char[] returnPsw;
private static boolean randomCollector = false;
private static ResourceBundle languagesBundle;
private NewPasswordDialog(Object owner, String messageString, String hint, Point location) {
super((Window)owner);
languagesBundle = PeaProperties.getBundle();
int fontSize = PswDialogView.getFontsize();
// show passwordField
newPswDialog = this;
newPswDialog.setAlwaysOnTop(true);
newPswDialog.setModal(true);
newPswDialog.setIconImage(PswDialogView.getImage() );
newPswDialog.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize));
newPswDialog.setLayout(new BoxLayout(newPswDialog.getContentPane(), BoxLayout.Y_AXIS));
if(randomCollector == true){
newPswDialog.addMouseMotionListener(new MouseRandomCollector() );
}
JPanel messageLabelPanel = new JPanel();
messageLabelPanel.setLayout(new BoxLayout(messageLabelPanel, BoxLayout.X_AXIS));
messageLabel = new JLabel(messageString);
messageLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize));
messageLabel.setPreferredSize(new Dimension(300,30));
if (messageString.equals(languagesBundle.getString("initialization"))
|| messageString.equals(languagesBundle.getString("change_password"))){
messageLabel.setForeground(new Color(0, 80, 0));//dark green
} else {
messageLabel.setForeground(Color.RED);
}
messageLabelPanel.add(messageLabel);
newPswDialog.add(messageLabelPanel);
JPanel pswLabelPanel = new JPanel();
pswLabelPanel.setLayout(new BoxLayout(pswLabelPanel, BoxLayout.X_AXIS));
JLabel pswLabel = new JLabel(languagesBundle.getString("enter_new_password"));
pswLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize));pswLabelPanel.add(pswLabel);
pswLabelPanel.add(Box.createHorizontalStrut(20));
qualityLabel = new JLabel();
qualityLabel.setFont(new Font(Font.SERIF, Font.ITALIC, fontSize + 2));
pswLabelPanel.add(qualityLabel);
pswLabelPanel.add(Box.createHorizontalStrut(5));
qualityLabelStars = new JLabel();
qualityLabelStars.setOpaque(true);
qualityLabelStars.setMaximumSize(new Dimension (300, 10));
//qualityLabelStars.setBackground(Color.WHITE);
qualityLabelStars.setFont(new Font(Font.MONOSPACED, Font.PLAIN, fontSize + 4));
pswLabelPanel.add(qualityLabelStars);
pswLabelPanel.add(Box.createHorizontalGlue());
JButton charTableButton = new JButton(languagesBundle.getString("char_table"));
charTableButton.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize - 2));
charTableButton.addActionListener(this);
charTableButton.setActionCommand("charTable1");
if(randomCollector == true){
charTableButton.addMouseMotionListener(new MouseRandomCollector() );
}
pswLabelPanel.add(charTableButton);
newPswDialog.add(pswLabelPanel);
newPasswordField = new JPasswordField(50);
newPasswordField.setActionCommand("newPsw");// Enter
newPasswordField.addActionListener(this);
if(randomCollector == true){
newPasswordField.addKeyListener(new KeyRandomCollector() );
}
// if the event comes from CharTable or virtual Keyboard
// two events are received because CharTable must replace
// the current password (remove and insert)
newPasswordField.getDocument().addDocumentListener(this);
newPswDialog.add(newPasswordField);
newPswDialog.add(Box.createVerticalStrut(10));
JPanel pswLabelPanel2 = new JPanel();
pswLabelPanel2.setLayout(new BoxLayout(pswLabelPanel2, BoxLayout.X_AXIS));
JLabel pswLabel2 = new JLabel(languagesBundle.getString("retype_password"));
pswLabel2.setPreferredSize(new Dimension(300,30));
pswLabel2.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize));
pswLabelPanel2.add(pswLabel2);
pswLabelPanel2.add(Box.createHorizontalGlue());
JButton charTableButton2 = new JButton(languagesBundle.getString("char_table"));
charTableButton2.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize - 2));
charTableButton2.addActionListener(this);
charTableButton2.setActionCommand("charTable2");
if(randomCollector == true){
charTableButton2.addMouseMotionListener(new MouseRandomCollector() );
}
pswLabelPanel2.add(charTableButton2);
newPswDialog.add(pswLabelPanel2);
retypePasswordField = new JPasswordField(50);
retypePasswordField.setActionCommand("retypePsw");// Enter
retypePasswordField.addActionListener(this);
if(randomCollector == true){
retypePasswordField.addKeyListener(new KeyRandomCollector() );
}
newPswDialog.add(retypePasswordField);
if (hint != null) {
JPanel hintPanel = new JPanel();
hintPanel.setLayout(new BoxLayout(hintPanel, BoxLayout.X_AXIS));
hintLabel = new JLabel(hint);
hintLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, fontSize));
//hintLabel.setPreferredSize(new Dimension(300,30));
hintPanel.add(hintLabel);
hintPanel.add(Box.createHorizontalGlue());
newPswDialog.add(hintPanel);
}
JPanel okPanel = new JPanel();
if(randomCollector == true){
okPanel.addMouseMotionListener(new MouseRandomCollector() );
}
okPanel.setLayout(new BoxLayout(okPanel, BoxLayout.X_AXIS));
JButton newPswButton = new JButton(languagesBundle.getString("ok"));
if(randomCollector == true){
newPswButton.addMouseMotionListener(new MouseRandomCollector() );
}
newPswButton.addActionListener(this);
newPswButton.setActionCommand("newPsw");// ok-Button
okPanel.add(Box.createHorizontalGlue());
okPanel.add(newPswButton);
newPswDialog.add(okPanel);
JPanel contentPane = (JPanel) newPswDialog.getContentPane();
contentPane.setBorder(PeaBorderFactory.createBorder(false));
//newPswDialog.setSize( 400, 170);
newPswDialog.setMinimumSize( new Dimension(400, 170));
newPswDialog.pack();
newPswDialog.setLocation(location);
newPswDialog.setVisible(true);
}
public final static NewPasswordDialog getInstance(
Object owner, String messageString, String hint, Point loc) {
if (newPswDialog == null) {
newPswDialog = new NewPasswordDialog(owner, messageString, hint, loc);
} else {
//
}
return newPswDialog;
}
public final char[] getDialogInput() {
newPswDialog = null;
return returnPsw;
}
public void setMessage(String message) {
// error message: foreground red
messageLabel.setForeground(Color.RED);
messageLabel.setText(message);
}
/* public void setHint(String hint) {
hintLabel.setForeground(new Color(0, 80, 0));//dark green
hintLabel.setText(hint);
newPswDialog.revalidate();
newPswDialog.repaint();
} */
private final void updatePasswordCheck() {
char[] pwd = newPasswordField.getPassword();
int quality = PasswordQualityCheck.checkQuality(pwd);//pswField.getPassword() );
// display at most 24 stars:
if (quality > 24){
quality = 24;
}
if (pwd != null){
Zeroizer.zero(pwd);
}
pwd = null;
char[] q = new char[quality];
//Arrays.fill(q, '*');
Arrays.fill(q, ' ');
if (quality < 12) {
qualityLabel.setText(PeaProperties.getBundle().getString("weak"));
qualityLabelStars.setText(new String(q));
//qualityLabelStars.setForeground(Color.RED);
qualityLabelStars.setBackground(Color.RED);
} else if (quality < 16) {
qualityLabel.setText(PeaProperties.getBundle().getString("medium"));
qualityLabelStars.setText(new String(q));
//qualityLabelStars.setForeground(Color.YELLOW);
qualityLabelStars.setBackground(Color.YELLOW);
} else {
qualityLabel.setText(PeaProperties.getBundle().getString("strong"));
qualityLabelStars.setText(new String(q));
//qualityLabelStars.setForeground(Color.GREEN);
qualityLabelStars.setBackground(Color.GREEN);
}
}
//
// derive keys from password and set new keys in CryptStuff
//
@Override
public void actionPerformed(ActionEvent ape) {
String com = ape.getActionCommand();
if ( com.startsWith("charTable")) {
if(com.equals("charTable1")){
CharTable table = new CharTable(this, newPasswordField, 0);
table.setVisible(true);
} else {
CharTable table = new CharTable(this, retypePasswordField, 0);
table.setVisible(true);
}
} else {//if (com.equals("newPsw")) {
// get password
char[] newPsw = newPasswordField.getPassword();
char[] retypePsw = retypePasswordField.getPassword();
if (retypePsw.length == 0 && newPsw.length != 0) {
setMessage(languagesBundle.getString("must_retype_password"));
return;
}
if (newPsw.length != retypePsw.length) {
setMessage(languagesBundle.getString("password_not_equal"));
newPasswordField.setText("");
retypePasswordField.setText("");
qualityLabelStars.setText("");
return;
}
boolean pswEqual = true;
for (int i = 0; i < newPsw.length; i++) {
if (newPsw[i] != retypePsw[i]) {
pswEqual = false;
}
}
if (pswEqual == false) {
setMessage(languagesBundle.getString("password_not_equal"));
newPasswordField.setText("");
retypePasswordField.setText("");
qualityLabelStars.setText("");
return;
}
if (newPsw.length == 0){
// On some systems the warning message is displayed
// behind the dialog otherwise:
newPswDialog.setAlwaysOnTop(false);
// allow null-passwords with warning
JOptionPane.showMessageDialog(newPswDialog,
languagesBundle.getString("null_password_chosen"),
languagesBundle.getString("warning"),
JOptionPane.WARNING_MESSAGE);
newPsw = "no password".toCharArray();
}
returnPsw = newPsw;
//System.out.println("NewPasswordDialog actioPerformed psw: " + new String(returnPsw) );
if (retypePsw.length > 0){
Zeroizer.zero(retypePsw);
}
newPasswordField.setText("");
this.dispose();
}
}
/**
* @return the randomCollector
*/
public static boolean isRandomCollector() {
return randomCollector;
}
/**
* @param randomCollector the randomCollector to set
*/
public static void setRandomCollector(boolean _randomCollector) {
NewPasswordDialog.randomCollector = _randomCollector;
}
@Override
public void changedUpdate(DocumentEvent arg0) {}
@Override
public void insertUpdate(DocumentEvent arg0) {
//System.out.println("insert");
updatePasswordCheck();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
//System.out.println("remove");
updatePasswordCheck();
}
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleNewPasswordDialog();
}
return accessibleContext;
}
@SuppressWarnings("serial")
protected class AccessibleNewPasswordDialog extends AccessibleJDialog {
//Inherit everything, override nothing.
}
}