-
Ludovic Apvrille authoredLudovic Apvrille authored
JDialogAttackerPopulation.java 19.04 KiB
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
*
* ludovic.apvrille AT enst.fr
*
* This software is a computer program whose purpose is to allow the
* edition of TURTLE analysis, design and deployment diagrams, to
* allow the generation of RT-LOTOS or Java code from this diagram,
* and at last to allow the analysis of formal validation traces
* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
* from INRIA Rhone-Alpes.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
package ui.window;
import attacktrees.*;
import common.ConfigurationTTool;
import myutil.Conversion;
import myutil.TraceManager;
import ui.MainGUI;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
/**
* Class JDialogAttackerPopulation
* Dialog for managing an attacker population
* Creation: 04/02/2021
*
* @author Ludovic APVRILLE
* @version 2.0 04/02/2021
*/
public class JDialogAttackerPopulation extends JDialogBase implements ActionListener, ListSelectionListener, Runnable {
protected AttackerPopulation population;
protected ArrayList<AttackerGroup> groups;
protected JPanel panel1, panel2;
protected MainGUI mgui;
protected Frame frame;
protected String attrib = "Attacker group";
// Name of population
protected String name;
protected JPanel panelName;
protected JTextField nameField;
// Panel1
protected JComboBox<String> expertise;
protected JTextField identifierText;
protected JTextField moneyText;
protected JTextField nbText;
protected JButton addButton;
//Panel2
protected JList<AttackerGroup> listAttackers;
protected JButton upButton;
protected JButton downButton;
protected JButton removeButton;
protected JButton analyzeButton;
protected JTextArea resultArea;
private boolean hasBeenCancelled = true;
/* Creates new form */
public JDialogAttackerPopulation(MainGUI _mgui, Frame f,
String title, AttackerPopulation _population) {
super(f, title, true);
mgui = _mgui;
frame = f;
population = _population;
name = population.getName();
groups = new ArrayList<>();
groups.addAll(population.getAttackerGroups());
initComponents();
myInitComponents();
pack();
}
protected void myInitComponents() {
removeButton.setEnabled(false);
upButton.setEnabled(false);
downButton.setEnabled(false);
}
protected void initComponents() {
Container c = getContentPane();
GridBagLayout gridbag0 = new GridBagLayout();
GridBagLayout gridbag1 = new GridBagLayout();
GridBagLayout gridbag2 = new GridBagLayout();
GridBagConstraints c0 = new GridBagConstraints();
GridBagConstraints c1 = new GridBagConstraints();
GridBagConstraints c2 = new GridBagConstraints();
setFont(new Font("Helvetica", Font.PLAIN, 14));
c.setLayout(gridbag0);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
panel1 = new JPanel();
panel1.setLayout(gridbag1);
panel1.setBorder(new javax.swing.border.TitledBorder("Adding " + attrib + "s"));
panel1.setPreferredSize(new Dimension(300, 250));
panel2 = new JPanel();
panel2.setLayout(gridbag2);
panel2.setBorder(new javax.swing.border.TitledBorder("Managing " + attrib + "s"));
panel2.setPreferredSize(new Dimension(300, 250));
// first line panel1
c1.gridwidth = 1;
c1.gridheight = 1;
c1.weighty = 1.0;
c1.weightx = 1.0;
c1.gridwidth = GridBagConstraints.REMAINDER; //end row
c1.fill = GridBagConstraints.BOTH;
c1.gridheight = 3;
panel1.add(new JLabel(" "), c1);
c1.gridwidth = 1;
c1.gridheight = 1;
c1.weighty = 1.0;
c1.weightx = 1.0;
c1.anchor = GridBagConstraints.CENTER;
panel1.add(new JLabel("Identifier"), c1);
panel1.add(new JLabel("Resource ($ / €)"), c1);
panel1.add(new JLabel("Expertise"), c1);
panel1.add(new JLabel(" "), c1);
c1.gridwidth = GridBagConstraints.REMAINDER; //end row
panel1.add(new JLabel("How many of them?"), c1);
// Second line panel1
c1.gridwidth = 1;
c1.fill = GridBagConstraints.HORIZONTAL;
c1.anchor = GridBagConstraints.CENTER;
identifierText = new JTextField();
identifierText.setColumns(15);
identifierText.setEditable(true);
panel1.add(identifierText, c1);
moneyText = new JTextField();
moneyText.setColumns(15);
moneyText.setEditable(true);
panel1.add(moneyText, c1);
expertise = new JComboBox<>(Attack.EXPERIENCES);
panel1.add(expertise, c1);
panel1.add(new JLabel(" "), c1);
c1.gridwidth = GridBagConstraints.REMAINDER; //end row
nbText = new JTextField();
nbText.setColumns(10);
nbText.setEditable(true);
panel1.add(nbText, c1);
c1.anchor = GridBagConstraints.CENTER;
// third line panel1
c1.gridwidth = GridBagConstraints.REMAINDER; //end row
c1.fill = GridBagConstraints.BOTH;
c1.gridheight = 3;
panel1.add(new JLabel(" "), c1);
// fourth line panel2
c1.gridheight = 1;
c1.fill = GridBagConstraints.HORIZONTAL;
addButton = new JButton("Add / Modify " + attrib);
addButton.addActionListener(this);
panel1.add(addButton, c1);
// 1st line panel2
listAttackers = new JList<AttackerGroup>(groups.toArray(new AttackerGroup[0]));
//listAttribute.setFixedCellWidth(150);
//listAttribute.setFixedCellHeight(20);
listAttackers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listAttackers.addListSelectionListener(this);
JScrollPane scrollPane = new JScrollPane(listAttackers);
scrollPane.setSize(300, 250);
c2.gridwidth = GridBagConstraints.REMAINDER; //end row
c2.fill = GridBagConstraints.BOTH;
c2.gridheight = 5;
c2.weighty = 10.0;
c2.weightx = 10.0;
panel2.add(scrollPane, c2);
// 2nd line panel2
c2.weighty = 1.0;
c2.weightx = 1.0;
c2.fill = GridBagConstraints.BOTH;
c2.gridheight = 1;
panel2.add(new JLabel(""), c2);
// third line panel2
c2.gridwidth = GridBagConstraints.REMAINDER; //end row
c2.fill = GridBagConstraints.HORIZONTAL;
upButton = new JButton("Up");
upButton.addActionListener(this);
panel2.add(upButton, c2);
downButton = new JButton("Down");
downButton.addActionListener(this);
panel2.add(downButton, c2);
removeButton = new JButton("Remove " + attrib);
removeButton.addActionListener(this);
panel2.add(removeButton, c2);
//Name panel
if (name != null) {
GridBagLayout gbOp = new GridBagLayout();
GridBagConstraints cOp = new GridBagConstraints();
panelName = new JPanel();
panelName.setLayout(gbOp);
panelName.setBorder(new javax.swing.border.TitledBorder("Name"));
//panelOperation.setPreferredSize(new Dimension(500, 70));
cOp.weighty = 1.0;
cOp.weightx = 2.0;
cOp.gridwidth = GridBagConstraints.REMAINDER;
cOp.fill = GridBagConstraints.BOTH;
cOp.gridheight = 3;
nameField = new JTextField(name);
panelName.add(nameField, cOp);
c0.weighty = 1.0;
c0.weightx = 1.0;
c0.fill = GridBagConstraints.BOTH;
c0.gridwidth = GridBagConstraints.REMAINDER;
c.add(panelName, c0);
}
// main panel;
c0.gridwidth = 1;
c0.gridheight = 15;
c0.weighty = 1.0;
c0.weightx = 1.0;
c0.fill = GridBagConstraints.BOTH;
c.add(panel1, c0);
c0.gridwidth = GridBagConstraints.REMAINDER; //end row
c.add(panel2, c0);
// Analysis panel
c0.gridheight = 1;
analyzeButton = new JButton("Analyze");
analyzeButton.addActionListener(this);
c.add(analyzeButton, c0);
JPanel jta = new JPanel();
jta.setBorder(new javax.swing.border.TitledBorder("Results"));
Font f = new Font("Courrier", Font.BOLD, 12);
jta.setFont(f);
resultArea = new JTextArea();
JScrollPane jsp = new JScrollPane(resultArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//jsp.setPreferredSize(new Dimension(600, 150));
//jta.add(jsp);
resultArea.append("Click on \"Analyse\" to analyse the current population");
c0.gridheight = 25;
c.add(jsp, c0);
c0.gridheight = 1;
c0.gridwidth = GridBagConstraints.REMAINDER;
c0.fill = GridBagConstraints.HORIZONTAL;
initButtons(c0, c, this);
}
public void actionPerformed(ActionEvent evt) {
String command = evt.getActionCommand();
// Compare the action command to the known actions.
if (command.equals("Save and Close")) {
closeDialog();
} else if (command.equals("Add / Modify " + attrib)) {
addAttackerGroup();
} else if (command.equals("Cancel")) {
cancelDialog();
} else if (command.equals("Remove " + attrib)) {
removeAttacker();
} else if (command.equals("Down")) {
downAttribute();
} else if (command.equals("Up")) {
upAttribute();
} else if (evt.getSource() == analyzeButton) {
Thread t = new Thread(this);
t.start();
}
}
public void addAttackerGroup() {
String s = identifierText.getText();
if (s.length() > 0) {
if (Attacker.isValidID(s)) {
int index = -1;
int cpt = 0;
for (AttackerGroup ag : groups) {
if (ag.getName().compareTo(s) == 0) {
index = cpt;
break;
}
cpt++;
}
// Found
if (index > -1) {
TraceManager.addDev("Found attacker group");
AttackerGroup ag = groups.get(index);
String tmp = moneyText.getText();
if (Conversion.isInteger(tmp)) {
ag.attacker.money = Integer.decode(tmp);
}
ag.attacker.expertise = expertise.getSelectedIndex();
tmp = nbText.getText();
if (Conversion.isInteger(tmp)) {
ag.occurrence = Integer.decode(tmp);
}
// not found
} else {
TraceManager.addDev("NOT Found attacker group");
AttackerGroup ag = new AttackerGroup(s, this);
groups.add(ag);
String tmp = moneyText.getText();
if (Attacker.isValidMoney(tmp)) {
ag.attacker.money = Integer.decode(tmp);
} else {
ag.attacker.money = 0;
}
ag.attacker.expertise = expertise.getSelectedIndex();
tmp = nbText.getText();
if (AttackerGroup.isValidOccurrence(tmp)) {
ag.occurrence = Integer.decode(tmp);
} else {
ag.occurrence = 1;
}
}
listAttackers.setListData(groups.toArray(new AttackerGroup[0]));
identifierText.setText("");
} else {
JOptionPane.showMessageDialog(frame,
"Bad identifier",
"Error",
JOptionPane.INFORMATION_MESSAGE);
return;
}
} else {
JOptionPane.showMessageDialog(frame,
"Bad identifier: identifier already in use, or invalid identifier",
"Error",
JOptionPane.INFORMATION_MESSAGE);
return;
}
}
public void removeAttacker() {
int i = listAttackers.getSelectedIndex();
if (i != -1) {
AttackerGroup ag = groups.get(i);
groups.remove(i);
listAttackers.setListData(groups.toArray(new AttackerGroup[0]));
}
}
public void downAttribute() {
int i = listAttackers.getSelectedIndex();
if ((i != -1) && (i != groups.size() - 1)) {
AttackerGroup o = groups.get(i);
groups.remove(i);
groups.add(i + 1, o);
listAttackers.setListData(groups.toArray(new AttackerGroup[0]));
listAttackers.setSelectedIndex(i + 1);
}
}
public void upAttribute() {
int i = listAttackers.getSelectedIndex();
if (i > 0) {
AttackerGroup o = groups.get(i);
groups.remove(i);
groups.add(i - 1, o);
listAttackers.setListData(groups.toArray(new AttackerGroup[0]));
listAttackers.setSelectedIndex(i - 1);
}
}
public void closeDialog() {
population.setGroup(groups);
if (Attacker.isValidID(nameField.getText())) {
population.setName(nameField.getText());
}
hasBeenCancelled = false;
dispose();
}
public void cancelDialog() {
dispose();
}
public void valueChanged(ListSelectionEvent e) {
int i = listAttackers.getSelectedIndex();
if (i == -1) {
removeButton.setEnabled(false);
upButton.setEnabled(false);
downButton.setEnabled(false);
identifierText.setText("");
//initialValue.setText("");
} else {
AttackerGroup a = groups.get(i);
identifierText.setText(a.getName());
moneyText.setText("" + a.getMoney());
expertise.setSelectedIndex(a.getExpertise());
nbText.setText("" + a.getOccurrence());
removeButton.setEnabled(true);
if (i > 0) {
upButton.setEnabled(true);
} else {
upButton.setEnabled(false);
}
if (i != groups.size() - 1) {
downButton.setEnabled(true);
} else {
downButton.setEnabled(false);
}
}
}
public void select(JComboBox<String> jcb, String text) {
String s;
for (int i = 0; i < jcb.getItemCount(); i++) {
s = jcb.getItemAt(i);
//
if (s.equals(text)) {
jcb.setSelectedIndex(i);
return;
}
}
}
public String getName() {
if (nameField != null) {
return nameField.getText().trim();
}
return "";
}
public boolean hasBeenCancelled() {
return hasBeenCancelled;
}
// Analysis
public void run() {
// Must check the syntax of the system
resultArea.append("\n\nRunning analysis\n");
resultArea.append("\tSyntax checking\n");
if (!mgui.checkModelingSyntax(true)) {
resultArea.append("\t\t-> KO\n");
return;
}
resultArea.append("\t\t-> OK\n");
resultArea.append("\tTree analysis\n");
AttackTree at = mgui.runAttackTreeAnalysis();
if (at == null) {
resultArea.append("\t\t-> KO\n");
return;
}
resultArea.append("\t\t-> OK\n");
AttackerPopulation pop = new AttackerPopulation(population.getName(), population.getReferenceObject());
pop.setGroup(groups);
int size = pop.getTotalPopulation();
int success = pop.getTotalAttackers(at);
resultArea.append("\tPopulation analysis\n");
resultArea.append("\t\tTotal population: " + size + "\n");
resultArea.append("\t\tSuccessful attackers: " + success + "\n");
resultArea.append("\t\t% of successful attackers: " + (int) (100.0 * success / size) + "%\n");
resultArea.append("\t\tProbability of success: " + ((double) success / size) + "\n");
// Using Z3
resultArea.append("\n\nRunning analysis with Z3\n");
resultArea.append("\nLoading Z3 libraries\n");
String ret = ConfigurationTTool.loadZ3Libs();
if (ret != null) {
resultArea.append("\nError - aborting. \n" + ret + "\n");
return;
}
AttackTreeSMTAnalysis analysis = new AttackTreeSMTAnalysis(at);
ArrayList<AttackerPopulation> aps = at.getAttackerPopulation();
for (AttackerPopulation ap : aps) {
ArrayList<AttackerGroup> ags = ap.getAttackerGroups();
for (AttackerGroup ag : ags) {
resultArea.append("\nTesting attacker: " + ag.attacker.getName() + "\n");
AttackTreeSMTSolution sol = analysis.computeSolution(ag.attacker);
resultArea.append("\tResult: " + sol.STATUS[sol.status] + "\n");
if (sol.status>sol.NO_SOLUTION) {
// End time
resultArea.append("\tUsed resources: " + sol.endTime + "\n");
// Attacks
String attacks = sol.getAttackStartEndTime();
if (attacks != null) {
resultArea.append("\tAttacks: name, start, end\n" + attacks + "\n");
}
}
}
}
}
}