/****************************************************************************** * * * Copyright 2017 Subterranean Security * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * * * *****************************************************************************/ package com.subterranean_security.crimson.viewer.ui.screen.generator.tabs; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Insets; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Date; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import javax.swing.Box; import javax.swing.DefaultComboBoxModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListCellRenderer; import javax.swing.SwingConstants; import javax.swing.border.EtchedBorder; import javax.swing.border.LineBorder; import javax.swing.border.TitledBorder; import com.subterranean_security.crimson.core.proto.Misc.AuthMethod; import com.subterranean_security.crimson.core.proto.Misc.AuthType; import com.subterranean_security.crimson.core.util.CryptoUtil; import com.subterranean_security.crimson.core.util.RandomUtil; import com.subterranean_security.crimson.viewer.store.ProfileStore; import com.subterranean_security.crimson.viewer.ui.UICommon; import com.subterranean_security.crimson.viewer.ui.UIUtil; import com.subterranean_security.crimson.viewer.ui.common.components.EntropyHarvester; public class ATab extends JPanel { private static final long serialVersionUID = 1L; private String group_text = "Group authentication is the most secure mechanism. A \"group key\" is embedded in the client and only servers that posses this key may authenticate with the client and vice versa."; private String pass_text = "A simple password is used to authenticate the client. Choose a strong password because the client will be able to authenticate with any server with the password installed."; private String none_text = "The client will request to skip authentication entirely. SSL/TLS will be used, but the identity of the client will be unverifiable."; public JComboBox<ImageIcon> authType; public JLabel key_prefix; public JTextField fld_group_name; private Timer timer = new Timer(); private GroupTimer gt = new GroupTimer(); public JComboBox<String> groupSelectionBox; private JPanel cards; private JTextArea txtAuthDescription; private JPasswordField passwordField; private JPasswordField passwordField_1; public JTextField fld_password_name; public JCheckBox chckbxDontInstallPassword; public ATab() { init(); loadGroups(); timer.schedule(gt, 0, 750); } public void init() { setLayout(new BorderLayout(0, 0)); JPanel panel_8 = new JPanel(); panel_8.setBorder(new TitledBorder(UICommon.basic, "Authentication Type", TitledBorder.LEADING, TitledBorder.TOP, null, null)); add(panel_8, BorderLayout.NORTH); panel_8.setLayout(new BorderLayout(0, 0)); txtAuthDescription = new JTextArea(); txtAuthDescription.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); txtAuthDescription.setFont(new Font("Dialog", Font.PLAIN, 10)); txtAuthDescription.setOpaque(false); txtAuthDescription.setWrapStyleWord(true); txtAuthDescription.setLineWrap(true); txtAuthDescription.setText(group_text); panel_8.add(txtAuthDescription, BorderLayout.CENTER); JPanel panel_10 = new JPanel(); panel_8.add(panel_10, BorderLayout.WEST); cards = new JPanel(); add(cards, BorderLayout.CENTER); cards.setLayout(new CardLayout(0, 0)); ImageIcon group = UIUtil.getIcon("icons16/general/group.png"); group.setDescription("Group"); ImageIcon password = UIUtil.getIcon("icons16/general/textfield_password.png"); password.setDescription("Password"); ImageIcon na = UIUtil.getIcon("icons16/general/radioactivity.png"); na.setDescription("None"); panel_10.setLayout(new BorderLayout(0, 0)); panel_10.add(Box.createHorizontalStrut(10), BorderLayout.EAST); panel_10.add(Box.createVerticalStrut(10), BorderLayout.SOUTH); JPanel panel = new JPanel(); panel_10.add(panel, BorderLayout.CENTER); panel.setLayout(new BorderLayout(0, 0)); authType = new JComboBox<ImageIcon>(); panel.add(authType, BorderLayout.NORTH); authType.setFont(new Font("Dialog", Font.BOLD, 10)); authType.setRenderer(new AuthComboBoxRenderer()); authType.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { refreshGroupSelection(); } }); authType.setModel(new DefaultComboBoxModel(new ImageIcon[] { group, password, na })); groupSelectionBox = new JComboBox<String>(); panel.add(groupSelectionBox, BorderLayout.SOUTH); groupSelectionBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { refreshGroupSelection(); } }); JPanel blank = new JPanel(); cards.add(blank, "blank"); JPanel authpanel_group = new JPanel(); cards.add(authpanel_group, "group"); authpanel_group.setLayout(new BorderLayout(0, 0)); JPanel panel_11 = new JPanel(); panel_11.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); authpanel_group.add(panel_11, BorderLayout.NORTH); panel_11.setLayout(new BorderLayout(0, 0)); JLabel lblGroupKeyPrefix = new JLabel("Group Key Prefix:"); lblGroupKeyPrefix.setFont(new Font("Dialog", Font.BOLD, 11)); panel_11.add(lblGroupKeyPrefix, BorderLayout.WEST); key_prefix = new JLabel("4 5 9 2 0 1 5 3 8 3 1 3 4 2 5 5"); key_prefix.setFont(new Font("Dialog", Font.BOLD, 11)); key_prefix.setHorizontalAlignment(SwingConstants.CENTER); panel_11.add(key_prefix, BorderLayout.CENTER); JPanel panel_12 = new JPanel(); authpanel_group.add(panel_12); panel_12.setLayout(new BorderLayout(0, 0)); JPanel panel_13 = new JPanel(); panel_13.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "Create new group", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(51, 51, 51))); panel_12.add(panel_13, BorderLayout.NORTH); panel_13.setLayout(new BorderLayout(0, 0)); JLabel lblGroupName = new JLabel(" Group Name:"); lblGroupName.setFont(new Font("Dialog", Font.BOLD, 10)); panel_13.add(lblGroupName, BorderLayout.WEST); JPanel panel_14 = new JPanel(); panel_13.add(panel_14, BorderLayout.EAST); fld_group_name = new JTextField(); fld_group_name.setBounds(130, 20, 117, 19); panel_14.add(fld_group_name); fld_group_name.setColumns(10); JButton btnRandom_1 = new JButton("Randomize"); btnRandom_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { fld_group_name.setText("Grp-" + RandomUtil.randString(5)); } }); btnRandom_1.setMargin(new Insets(2, 2, 2, 2)); btnRandom_1.setFont(new Font("Dialog", Font.BOLD, 9)); btnRandom_1.setBounds(259, 20, 70, 19); panel_14.add(btnRandom_1); EntropyHarvester eh = new EntropyHarvester(); eh.hpanel.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent e) { gt.mix(e.getPoint()); } }); panel_12.add(eh, BorderLayout.CENTER); JPanel authpanel_password = new JPanel(); authpanel_password.setBorder(new TitledBorder(UICommon.basic, "Password Authentication", TitledBorder.LEADING, TitledBorder.TOP, null, null)); cards.add(authpanel_password, "Password"); authpanel_password.setLayout(null); JLabel lblPassword = new JLabel("Password"); lblPassword.setFont(new Font("Dialog", Font.BOLD, 10)); lblPassword.setBounds(220, 20, 66, 18); authpanel_password.add(lblPassword); JLabel lblRetype = new JLabel("Retype:"); lblRetype.setFont(new Font("Dialog", Font.BOLD, 10)); lblRetype.setBounds(220, 42, 66, 18); authpanel_password.add(lblRetype); passwordField = new JPasswordField(); passwordField.setBounds(314, 20, 126, 18); authpanel_password.add(passwordField); passwordField_1 = new JPasswordField(); passwordField_1.setBounds(314, 42, 126, 18); authpanel_password.add(passwordField_1); fld_password_name = new JTextField(); fld_password_name.setBounds(79, 20, 108, 18); authpanel_password.add(fld_password_name); fld_password_name.setColumns(10); JLabel lblName = new JLabel("Name:"); lblName.setFont(new Font("Dialog", Font.BOLD, 10)); lblName.setBounds(12, 20, 66, 18); authpanel_password.add(lblName); chckbxDontInstallPassword = new JCheckBox("Don't install password on server"); chckbxDontInstallPassword.setFont(new Font("Dialog", Font.BOLD, 10)); chckbxDontInstallPassword.setBounds(12, 80, 258, 23); authpanel_password.add(chckbxDontInstallPassword); JPanel authpanel_none = new JPanel(); cards.add(authpanel_none, "None"); JLabel lblNewLabel = new JLabel("Warning: Authentication mode is set to NONE"); lblNewLabel.setFont(new Font("Dialog", Font.BOLD, 10)); authpanel_none.add(lblNewLabel); JLabel lblThisClientWill = new JLabel("This client will be able to authenticate with any server!"); lblThisClientWill.setFont(new Font("Dialog", Font.BOLD, 10)); authpanel_none.add(lblThisClientWill); } private void loadGroups() { ArrayList<AuthMethod> groups = new ArrayList<AuthMethod>(); for (AuthMethod am : ProfileStore.getServer().authMethods) { if (am.getType() == AuthType.GROUP) { groups.add(am); } } String[] g = new String[groups.size() + 1]; g[g.length - 1] = "Create Group"; for (int i = 0; i < g.length - 1; i++) { g[i] = groups.get(i).getName(); } groupSelectionBox.setModel(new DefaultComboBoxModel<String>(g)); refreshGroupSelection(); } private void refreshGroupSelection() { switch (((ImageIcon) authType.getSelectedItem()).getDescription()) { case "Group": { txtAuthDescription.setText(group_text); if (((String) groupSelectionBox.getSelectedItem()).equals("Create Group")) { ((CardLayout) cards.getLayout()).show(cards, "group"); } else { ((CardLayout) cards.getLayout()).show(cards, "blank"); } groupSelectionBox.setVisible(true); break; } case "Password": { txtAuthDescription.setText(pass_text); ((CardLayout) cards.getLayout()).show(cards, "Password"); groupSelectionBox.setVisible(false); break; } case "None": { txtAuthDescription.setText(none_text); ((CardLayout) cards.getLayout()).show(cards, "None"); groupSelectionBox.setVisible(false); break; } } } class GroupTimer extends TimerTask { private Random rand = new Random(); private String last = "" + new Date().getTime(); private int upper = 20; private int lower = 10; @Override public void run() { hash(); display(50); } private void hash() { last = CryptoUtil.hashSign(last, RandomUtil.randString(rand.nextInt(upper - lower + 1) + lower)) .replaceAll("\\+|/", RandomUtil.randString(1)); } private void display(int delay) { String data = last; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 16; i++) { sb.append(' '); sb.append(data.charAt(i)); } key_prefix.setText(""); try { Thread.sleep(delay); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } key_prefix.setText(sb.toString().substring(1).toUpperCase()); } public void mix(Point p) { last += p.x + p.y; hash(); display(0); } } public void cancelTimer() { timer.cancel(); timer = null; } public String getGroupPrefix() { try { return CryptoUtil.hash("SHA-256", key_prefix.getText().toCharArray()); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public String getPassword() { return UIUtil.getPassword(passwordField); } public class AuthComboBoxRenderer extends JLabel implements ListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { ImageIcon icon = (ImageIcon) value; setIcon(icon); setText(icon.getDescription()); return this; } } }