diff --git a/build.txt b/build.txt index 7240aefe82f413e7ea50a1435ce578bcb764fe5e..40362824b3b89c1b38ff5fc88e69bffda884a3ff 100644 --- a/build.txt +++ b/build.txt @@ -1 +1 @@ -14813 \ No newline at end of file +14815 \ No newline at end of file diff --git a/src/main/java/attacktrees/AttackTree.java b/src/main/java/attacktrees/AttackTree.java index ce84eba229be692ce8ccf7d13d60e5ce2c41abbf..edae32c3f7309ee9bdee1b090236dd68d4ec83b4 100644 --- a/src/main/java/attacktrees/AttackTree.java +++ b/src/main/java/attacktrees/AttackTree.java @@ -56,6 +56,7 @@ import java.util.HashMap; public class AttackTree extends AttackElement { private ArrayList<AttackNode> nodes; private ArrayList<Attack> attacks; + private ArrayList<Defense> defenses; public AttackElement faultyElement; public String errorOfFaultyElement; @@ -67,6 +68,7 @@ public class AttackTree extends AttackElement { super(_name, _reference); nodes = new ArrayList<>(); attacks = new ArrayList<>(); + defenses = new ArrayList<>(); populations = new ArrayList<>(); } @@ -78,6 +80,10 @@ public class AttackTree extends AttackElement { attacks.add(_attack); } + public void addDefense(Defense _def) { + defenses.add(_def); + } + public void addPopulation(AttackerPopulation _ap) {populations.add(_ap);} public String toString() { @@ -93,6 +99,10 @@ public class AttackTree extends AttackElement { return attacks; } + public ArrayList<Defense> getDefenses() { + return defenses; + } + public ArrayList<AttackNode> getAttackNodes() { return nodes; } @@ -218,5 +228,59 @@ public class AttackTree extends AttackElement { } + public String toTextFormat() { + StringBuffer sb = new StringBuffer(); + + int cpt = 0; + sb.append("Attacks:\n"); + for(Attack att: attacks) { + sb.append("\t" + cpt + ". " + att.getName()); + if (att.isRoot()) { + sb.append(" (root)"); + } else if (att.isLeaf()) { + sb.append(" (leaf)"); + } + if (att.getDescription() != null) { + sb.append(". " + att.getDescription()); + } + sb.append("\n"); + cpt ++; + } + + cpt = 0; + sb.append("\nNodes:\n"); + for(AttackNode node: nodes) { + sb.append("\t" + cpt + ". " + node.getType() + "\n"); + sb.append("\t\tinput attacks: "); + for(Attack att: node.getInputAttacks()) { + sb.append(attacks.indexOf(att) + " "); + } + sb.append("\t\toutput attack: " + attacks.indexOf(node.getResultingAttack())); + cpt ++; + sb.append("\n"); + } + + cpt = 0; + sb.append("\nDefenses:\n"); + for(Defense def: defenses) { + sb.append("\t" + cpt + ". " + def.getName()); + if (def.getDescription() != null) { + sb.append(". " + def.getDescription()); + } + sb.append("\n"); + sb.append("\t\trelated attacks: "); + for(Attack att: def.getRelatedAttacks()) { + sb.append(attacks.indexOf(att) + " "); + } + cpt ++; + sb.append("\n"); + } + + + + + return sb.toString(); + } + } diff --git a/src/main/java/attacktrees/Defense.java b/src/main/java/attacktrees/Defense.java new file mode 100644 index 0000000000000000000000000000000000000000..80524661dca7cc8218037697338a51f3a8838a0d --- /dev/null +++ b/src/main/java/attacktrees/Defense.java @@ -0,0 +1,98 @@ +/* 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 attacktrees; + +import java.util.ArrayList; + + +/** + * Class Attack + * Creation: 10/04/2015 + * + * @author Ludovic APVRILLE + * @version 1.0 10/04/2015 + */ +public class Defense extends AttackElement { + + + private ArrayList<Attack> relatedAttacks; + private String description; + private boolean isEnabled; + + public Defense(String _name, Object _referenceObject) { + super(_name, _referenceObject); + relatedAttacks = new ArrayList<>(); + } + + + public String getDescription() { + return description; + } + + public void setDescription(String _description) { + description = _description; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean _enabled) { + isEnabled = _enabled; + } + + + public void addRelatedAttack(Attack _attack) { + + if (!relatedAttacks.contains(_attack)) + relatedAttacks.add(_attack); + } + + public ArrayList<Attack> getRelatedAttacks() { + return relatedAttacks; + } + + public String toString() { + String data = "Defense name: " + super.getName() + " Description: " + this.description; + + data += "\n"; + return data; + } +} diff --git a/src/main/java/ui/AttackTreePanelTranslator.java b/src/main/java/ui/AttackTreePanelTranslator.java index fe23a169ee5ba705e441b0369b61357941605248..44d9cb4e35ac36d387a1af054dc918e7b6abc766 100644 --- a/src/main/java/ui/AttackTreePanelTranslator.java +++ b/src/main/java/ui/AttackTreePanelTranslator.java @@ -58,6 +58,7 @@ public class AttackTreePanelTranslator { protected int index; protected AttackTree at; + protected AttackTreeDiagramPanel panel; protected AttackTreePanel atp; protected List<CheckingError> checkingErrors, warnings; protected CorrespondanceTGElement listE; // usual list @@ -71,6 +72,12 @@ public class AttackTreePanelTranslator { reinit(); } + public AttackTreePanelTranslator(AttackTreeDiagramPanel _panel) { + panel = _panel; + index = -1; + reinit(); + } + public AttackTreePanelTranslator(AttackTreePanel _atp, int _index) { atp = _atp; index = _index; @@ -105,12 +112,17 @@ public class AttackTreePanelTranslator { public AttackTree translateToAttackTreeDataStructure() { + at = new AttackTree("AttackTree", atp); - TDiagramPanel panel = atp.panels.get(index); + if (panel == null) { + panel = (AttackTreeDiagramPanel)(atp.panels.get(index)); + } - if ((panel != null) && (panel instanceof AttackTreeDiagramPanel)) { - translate((AttackTreeDiagramPanel) panel); + at = new AttackTree("AttackTree", panel); + if (panel != null) { + at = new AttackTree("AttackTree", atp); + translate(panel); boolean b = at.checkSyntax(); if (!b) { UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, at.errorOfFaultyElement); @@ -118,7 +130,6 @@ public class AttackTreePanelTranslator { ce.setTDiagramPanel(panel); addCheckingError(ce); } - return at; } @@ -135,7 +146,6 @@ public class AttackTreePanelTranslator { //Create attacks, nodes for (TGComponent comp : allComponents) { - // Population if (comp instanceof ATDAttackerPopulation) { ATDAttackerPopulation atdap = (ATDAttackerPopulation)comp; @@ -155,16 +165,26 @@ public class AttackTreePanelTranslator { father = atdatt.getFather(); if ((father != null) && (father instanceof ATDBlock)) { value = ((ATDBlock) father).getNodeName() + "__" + value; - } att = new Attack(value, atdatt); att.setRoot(atdatt.isRootAttack()); att.setEnabled(atdatt.isEnabled()); att.setAttackCost(atdatt.getAttackCost()); att.setAttackExperience(atdatt.getAttackExperience()); + att.setDescription(atdatt.getDescription()); at.addAttack(att); listE.addCor(att, comp); } + if (comp instanceof ATDCountermeasure) { + ATDCountermeasure atdc = (ATDCountermeasure) comp; + Defense def; + def = new Defense(comp.getValue(), comp); + def.setEnabled(atdc.isEnabled()); + def.setDescription(atdc.getDescription()); + at.addDefense(def); + listE.addCor(def, comp); + + } if (comp instanceof ATDConstraint) { ATDConstraint cons = (ATDConstraint) comp; nodeID++; @@ -234,8 +254,35 @@ public class AttackTreePanelTranslator { } } + // Making connections between countermeasures and attacks + // Counter -> attack + TGComponent tgc1, tgc2, tgctmp; + for (TGComponent comp : allComponents) { + if (comp instanceof ATDCountermeasureConnector) { + ATDCountermeasureConnector con = (ATDCountermeasureConnector) (comp); + tgc1 = atdp.getComponentToWhichBelongs(con.getTGConnectingPointP1()); + tgc2 = atdp.getComponentToWhichBelongs(con.getTGConnectingPointP2()); + if (tgc1 instanceof ATDAttack) { + tgctmp = tgc1; + tgc1 = tgc2; + tgc2 = tgctmp; + } + if ((tgc2 instanceof ATDAttack) && (tgc1 instanceof ATDCountermeasure)) { + try { + Defense def = (Defense) (listE.getObject(tgc1)); + Attack att = (Attack) (listE.getObject(tgc2)); + def.addRelatedAttack(att); + } catch (Exception e) { + UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Badly formed connector"); + ce.setTGComponent(comp); + ce.setTDiagramPanel(atdp); + addCheckingError(ce); + } + } + } + } // Making connections between nodes&attacks - TGComponent tgc1, tgc2; + for (TGComponent comp : allComponents) { if (comp instanceof ATDAttackConnector) { ATDAttackConnector con = (ATDAttackConnector) (comp); diff --git a/src/main/java/ui/AvatarPanelDrawer.java b/src/main/java/ui/AvatarPanelDrawer.java index 176e17608ae15e2f23c5fc272de97d495c44c4fa..f3953695577abb45ecf6cd9bcf51f368efcf6e69 100644 --- a/src/main/java/ui/AvatarPanelDrawer.java +++ b/src/main/java/ui/AvatarPanelDrawer.java @@ -227,19 +227,21 @@ public class AvatarPanelDrawer { TGConnectingPoint p1 = null, p2 = null; - if ((ar.getReferenceObject() instanceof AvatarBDPortConnector) && (ar.getOtherReferenceObjects().size() > 1)) { - //TraceManager.addDev("*----* Found reference objects before / after port connector"); - AvatarBDPortConnector connOld = (AvatarBDPortConnector) (ar.getReferenceObject()); - if ((ar.getOtherReferenceObjects().get(0) instanceof TGComponent) && (ar.getOtherReferenceObjects().get(1) instanceof TGComponent)) { - TGComponent tgc1 = (TGComponent) (ar.getOtherReferenceObjects().get(0)); - TGComponent tgc2 = (TGComponent) (ar.getOtherReferenceObjects().get(1)); - - int index1 = tgc1.getIndexOfTGConnectingPoint(connOld.getTGConnectingPointP1()); - int index2 = tgc2.getIndexOfTGConnectingPoint(connOld.getTGConnectingPointP2()); - - if ((index1 != -1) && (index2 != -1)) { - p1 = b1.getFreeTGConnectingPoint(index1); - p2 = b2.getFreeTGConnectingPoint(index2); + if (ar.getOtherReferenceObjects() != null) { + if ((ar.getReferenceObject() instanceof AvatarBDPortConnector) && (ar.getOtherReferenceObjects().size() > 1)) { + //TraceManager.addDev("*----* Found reference objects before / after port connector"); + AvatarBDPortConnector connOld = (AvatarBDPortConnector) (ar.getReferenceObject()); + if ((ar.getOtherReferenceObjects().get(0) instanceof TGComponent) && (ar.getOtherReferenceObjects().get(1) instanceof TGComponent)) { + TGComponent tgc1 = (TGComponent) (ar.getOtherReferenceObjects().get(0)); + TGComponent tgc2 = (TGComponent) (ar.getOtherReferenceObjects().get(1)); + + int index1 = tgc1.getIndexOfTGConnectingPoint(connOld.getTGConnectingPointP1()); + int index2 = tgc2.getIndexOfTGConnectingPoint(connOld.getTGConnectingPointP2()); + + if ((index1 != -1) && (index2 != -1)) { + p1 = b1.getFreeTGConnectingPoint(index1); + p2 = b2.getFreeTGConnectingPoint(index2); + } } } } @@ -260,11 +262,13 @@ public class AvatarPanelDrawer { points.add(p); }*/ - for (int i = 0; i < ar.getOtherReferenceObjects().size(); i++) { - Object o = ar.getOtherReferenceObjects().get(i); - if (o instanceof TGCPointOfConnector) { - TGCPointOfConnector op = (TGCPointOfConnector) o; - points.add(new Point(op.getX(), op.getY())); + if (ar.getOtherReferenceObjects() != null) { + for (int i = 0; i < ar.getOtherReferenceObjects().size(); i++) { + Object o = ar.getOtherReferenceObjects().get(i); + if (o instanceof TGCPointOfConnector) { + TGCPointOfConnector op = (TGCPointOfConnector) o; + points.add(new Point(op.getX(), op.getY())); + } } } diff --git a/src/main/java/ui/GTURTLEModeling.java b/src/main/java/ui/GTURTLEModeling.java index 2b35d1be292b64c21aa1873d08833cf861621193..31c433f3b33aa83f03263006339a821f5137e754 100644 --- a/src/main/java/ui/GTURTLEModeling.java +++ b/src/main/java/ui/GTURTLEModeling.java @@ -9592,6 +9592,14 @@ public class GTURTLEModeling { return avatarspec.toTextFormat(false, false, false); } + } else if (_tdp instanceof AttackTreeDiagramPanel) { + + AttackTreePanelTranslator atpt = new AttackTreePanelTranslator((AttackTreeDiagramPanel) _tdp); + AttackTree at = atpt.translateToAttackTreeDataStructure(); + if (at != null) { + return at.toTextFormat(); + } + } return null; } diff --git a/src/main/java/ui/util/DefaultText.java b/src/main/java/ui/util/DefaultText.java index 3a8ccfca87bafd6b72839574b8c07d8012b0e5aa..bfbe4de0454dd1258836226f9cc29bb404042065 100755 --- a/src/main/java/ui/util/DefaultText.java +++ b/src/main/java/ui/util/DefaultText.java @@ -50,8 +50,8 @@ package ui.util; */ public class DefaultText { - public static String BUILD = "14812"; - public static String DATE = "2024/06/17 03:21:58 CET"; + public static String BUILD = "14814"; + public static String DATE = "2024/06/19 03:22:26 CET"; public static StringBuffer sbAbout = makeAbout();