mal-toolbox 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,169 +10,170 @@ import xml.etree.ElementTree as ET
10
10
  from typing import Optional
11
11
 
12
12
  from ..model import AttackerAttachment, Model
13
- from ..language import LanguageGraph, LanguageClassesFactory
13
+ from ..language import LanguageGraph
14
14
 
15
15
  logger = logging.getLogger(__name__)
16
16
 
17
- def load_model_from_scad_archive(
18
- scad_archive: str,
19
- lang_graph: LanguageGraph,
20
- lang_classes_factory: LanguageClassesFactory
21
- ) -> Optional[Model]:
22
- """
23
- Reads a '.sCAD' archive generated by securiCAD representing an instance
24
- model and loads the information into a maltoobox.model.Model object.
25
-
26
- Arguments:
27
- scad_archive - the path to a '.sCAD' archive
28
- lang_graph - a language graph representing the MAL
29
- language specification
30
- lang_classes_factory - a language classes factory that contains
31
- the classes defined by the
32
- language specification
33
-
34
- Return:
35
- A maltoobox.model.Model object containing the instance model.
36
- """
37
- with zipfile.ZipFile(scad_archive, 'r') as archive:
38
- filelist = archive.namelist()
39
- model_file = next(filter(lambda x: ( x[-4:] == '.eom'), filelist))
40
- scad_model = archive.read(model_file)
41
- root = ET.fromstring(scad_model)
42
-
43
- instance_model = Model(scad_archive,
44
- lang_classes_factory)
45
-
46
- for child in root.iter('objects'):
47
-
48
- if logger.isEnabledFor(logging.DEBUG):
49
- # Avoid running json.dumps when not in debug
50
- logger.debug(
51
- 'Loading asset from "%s": \n%s',
52
- scad_archive, json.dumps(child.attrib, indent=2)
53
- )
54
-
55
- if child.attrib['metaConcept'] == 'Attacker':
56
- attacker_obj_id = int(child.attrib['id'])
57
- attacker_at = AttackerAttachment()
58
- attacker_at.entry_points = []
59
- instance_model.add_attacker(
60
- attacker_at,
61
- attacker_id = attacker_obj_id
62
- )
63
- continue
64
-
65
- if not hasattr(lang_classes_factory.ns,
66
- child.attrib['metaConcept']):
67
- logger.error(
68
- 'Failed to find %s asset in language specification!',
69
- child.attrib["metaConcept"]
70
- )
71
- return None
72
- asset = getattr(lang_classes_factory.ns,
73
- child.attrib['metaConcept'])(name = child.attrib['name'])
74
- asset_id = int(child.attrib['id'])
75
- for subchild in child.iter('evidenceAttributes'):
76
- defense_name = subchild.attrib['metaConcept']
77
- defense_name = defense_name[0].lower() + defense_name[1:]
78
- for distrib in subchild.iter('evidenceDistribution'):
79
- for d in distrib.iter('parameters'):
80
- if 'value' in d.attrib:
81
- dist_value = d.attrib['value']
82
- setattr(asset, defense_name, float(dist_value))
83
- instance_model.add_asset(asset, asset_id)
84
-
85
- for child in root.iter('associations'):
86
- logger.debug(
87
- 'Load association ("%s", "%s", "%s", "%s") from %s',
88
- child.attrib["sourceObject"], child.attrib["targetObject"],
89
- child.attrib["targetProperty"], child.attrib["sourceProperty"],
90
- scad_archive
91
- )
92
- # Note: This is not a bug in the code. The fields and assets are
93
- # listed incorrectly in the securiCAD format where the source asset
94
- # matches the target field and vice versa.
95
- left_id = int(child.attrib['targetObject'])
96
- right_id = int(child.attrib['sourceObject'])
97
- attacker_id = None
98
- if child.attrib['sourceProperty'] == 'firstSteps':
99
- attacker_id = right_id
100
- target_id = left_id
101
- target_prop = child.attrib['targetProperty']
102
- elif child.attrib['targetProperty'] == 'firstSteps':
103
- attacker_id = left_id
104
- target_id = right_id
105
- target_prop = child.attrib['sourceProperty']
106
-
107
- if attacker_id is not None:
108
- attacker = instance_model.get_attacker_by_id(attacker_id)
109
- if not attacker:
110
- logger.error(
111
- 'Failed to find attacker with id %s in model!',
112
- attacker_id
113
- )
114
- return None
115
- target_asset = instance_model.get_asset_by_id(target_id)
116
- if not target_asset:
117
- logger.error(
118
- 'Failed to find asset with id %s in model!',
119
- target_id
120
- )
121
- return None
122
- attacker.entry_points.append((target_asset,
123
- [target_prop.split('.')[0]]))
124
- continue
125
-
126
- left_asset = instance_model.get_asset_by_id(left_id)
127
- if not left_asset:
128
- logger.error(
129
- 'Failed to find asset with id %s in model!', left_id
130
- )
131
- return None
132
- right_asset = instance_model.get_asset_by_id(right_id)
133
- if not right_asset:
134
- logger.error(
135
- 'Failed to find asset with id %s in model!', right_id
136
- )
137
- return None
138
-
139
- # Note: This is not a bug in the code. The fields and assets are
140
- # listed incorrectly in the securiCAD format where the source asset
141
- # matches the target field and vice versa.
142
- left_field = child.attrib['sourceProperty']
143
- right_field = child.attrib['targetProperty']
144
- lang_graph_assoc = lang_graph.get_association_by_fields_and_assets(
145
- left_field,
146
- right_field,
147
- left_asset.type,
148
- right_asset.type)
149
-
150
- if not lang_graph_assoc:
151
- raise LookupError(
152
- 'Failed to find ("%s", "%s", "%s", "%s")'
153
- 'association in lang specification.' %
154
- (left_asset.type, right_asset.type,
155
- left_field, right_field)
156
- )
157
- return None
158
-
159
- logger.debug('Found "%s" association.', lang_graph_assoc.name)
160
- assoc_name = lang_classes_factory.get_association_by_signature(
161
- lang_graph_assoc.name,
162
- left_asset.type,
163
- right_asset.type
164
- )
165
-
166
- if assoc_name is None:
167
- logger.error(
168
- 'Failed to find association with name \"%s\" in model!',
169
- lang_graph_assoc.name
170
- )
171
- return None
172
-
173
- assoc = getattr(lang_classes_factory.ns, assoc_name)()
174
- setattr(assoc, left_field, [left_asset])
175
- setattr(assoc, right_field, [right_asset])
176
- instance_model.add_association(assoc)
177
-
178
- return instance_model
17
+ # TODO: Update this at some point
18
+
19
+ # def load_model_from_scad_archive(
20
+ # scad_archive: str,
21
+ # lang_graph: LanguageGraph
22
+ # ) -> Optional[Model]:
23
+ # """
24
+ # Reads a '.sCAD' archive generated by securiCAD representing an instance
25
+ # model and loads the information into a maltoobox.model.Model object.
26
+ #
27
+ # Arguments:
28
+ # scad_archive - the path to a '.sCAD' archive
29
+ # lang_graph - a language graph representing the MAL
30
+ # language specification
31
+ #
32
+ # Return:
33
+ # A maltoobox.model.Model object containing the instance model.
34
+ # """
35
+ # with zipfile.ZipFile(scad_archive, 'r') as archive:
36
+ # filelist = archive.namelist()
37
+ # model_file = next(filter(lambda x: ( x[-4:] == '.eom'), filelist))
38
+ # scad_model = archive.read(model_file)
39
+ # root = ET.fromstring(scad_model)
40
+ #
41
+ # instance_model = Model(scad_archive,
42
+ # lang_classes_factory)
43
+ #
44
+ # for child in root.iter('objects'):
45
+ #
46
+ # if logger.isEnabledFor(logging.DEBUG):
47
+ # # Avoid running json.dumps when not in debug
48
+ # logger.debug(
49
+ # 'Loading asset from "%s": \n%s',
50
+ # scad_archive, json.dumps(child.attrib, indent=2)
51
+ # )
52
+ #
53
+ # if child.attrib['metaConcept'] == 'Attacker':
54
+ # attacker_obj_id = int(child.attrib['id'])
55
+ # attacker_at = AttackerAttachment()
56
+ # attacker_at.entry_points = []
57
+ # instance_model.add_attacker(
58
+ # attacker_at,
59
+ # attacker_id = attacker_obj_id
60
+ # )
61
+ # continue
62
+ #
63
+ # if not hasattr(lang_classes_factory.ns,
64
+ # child.attrib['metaConcept']):
65
+ # logger.error(
66
+ # 'Failed to find %s asset in language specification!',
67
+ # child.attrib["metaConcept"]
68
+ # )
69
+ # return None
70
+ # asset = getattr(lang_classes_factory.ns,
71
+ # child.attrib['metaConcept'])(name = child.attrib['name'])
72
+ # asset_id = int(child.attrib['id'])
73
+ # for subchild in child.iter('evidenceAttributes'):
74
+ # defense_name = subchild.attrib['metaConcept']
75
+ # defense_name = defense_name[0].lower() + defense_name[1:]
76
+ # for distrib in subchild.iter('evidenceDistribution'):
77
+ # for d in distrib.iter('parameters'):
78
+ # if 'value' in d.attrib:
79
+ # dist_value = d.attrib['value']
80
+ # setattr(asset, defense_name, float(dist_value))
81
+ # instance_model.add_asset(asset, asset_id)
82
+ #
83
+ # for child in root.iter('associations'):
84
+ # logger.debug(
85
+ # 'Load association ("%s", "%s", "%s", "%s") from %s',
86
+ # child.attrib["sourceObject"], child.attrib["targetObject"],
87
+ # child.attrib["targetProperty"], child.attrib["sourceProperty"],
88
+ # scad_archive
89
+ # )
90
+ # # Note: This is not a bug in the code. The fields and assets are
91
+ # # listed incorrectly in the securiCAD format where the source asset
92
+ # # matches the target field and vice versa.
93
+ # left_id = int(child.attrib['targetObject'])
94
+ # right_id = int(child.attrib['sourceObject'])
95
+ # attacker_id = None
96
+ # if child.attrib['sourceProperty'] == 'firstSteps':
97
+ # attacker_id = right_id
98
+ # target_id = left_id
99
+ # target_prop = child.attrib['targetProperty']
100
+ # elif child.attrib['targetProperty'] == 'firstSteps':
101
+ # attacker_id = left_id
102
+ # target_id = right_id
103
+ # target_prop = child.attrib['sourceProperty']
104
+ #
105
+ # if attacker_id is not None:
106
+ # attacker = instance_model.get_attacker_by_id(attacker_id)
107
+ # if not attacker:
108
+ # logger.error(
109
+ # 'Failed to find attacker with id %s in model!',
110
+ # attacker_id
111
+ # )
112
+ # return None
113
+ # target_asset = instance_model.get_asset_by_id(target_id)
114
+ # if not target_asset:
115
+ # logger.error(
116
+ # 'Failed to find asset with id %s in model!',
117
+ # target_id
118
+ # )
119
+ # return None
120
+ # attacker.entry_points.append((target_asset,
121
+ # [target_prop.split('.')[0]]))
122
+ # continue
123
+ #
124
+ # left_asset = instance_model.get_asset_by_id(left_id)
125
+ # if not left_asset:
126
+ # logger.error(
127
+ # 'Failed to find asset with id %s in model!', left_id
128
+ # )
129
+ # return None
130
+ # right_asset = instance_model.get_asset_by_id(right_id)
131
+ # if not right_asset:
132
+ # logger.error(
133
+ # 'Failed to find asset with id %s in model!', right_id
134
+ # )
135
+ # return None
136
+ #
137
+ # # Note: This is not a bug in the code. The fields and assets are
138
+ # # listed incorrectly in the securiCAD format where the source asset
139
+ # # matches the target field and vice versa.
140
+ # left_field = child.attrib['sourceProperty']
141
+ # right_field = child.attrib['targetProperty']
142
+ # lang_graph_assoc = None
143
+ # for assoc in left_asset.lg_asset.associations:
144
+ # if (assoc.left_field.fieldname == left_field and
145
+ # assoc.right_field.fieldname == right_field) or \
146
+ # (assoc.left_field.fieldname == right_field and
147
+ # assoc.right_field.fieldname == left_field):
148
+ # lang_graph_assoc = assoc
149
+ # break
150
+ #
151
+ # if not lang_graph_assoc:
152
+ # raise LookupError(
153
+ # 'Failed to find ("%s", "%s", "%s", "%s")'
154
+ # 'association in lang specification.' %
155
+ # (left_asset.type, right_asset.type,
156
+ # left_field, right_field)
157
+ # )
158
+ # return None
159
+ #
160
+ # logger.debug('Found "%s" association.', lang_graph_assoc.name)
161
+ # assoc_name = lang_classes_factory.get_association_by_signature(
162
+ # lang_graph_assoc.name,
163
+ # left_asset.type,
164
+ # right_asset.type
165
+ # )
166
+ #
167
+ # if assoc_name is None:
168
+ # logger.error(
169
+ # 'Failed to find association with name \"%s\" in model!',
170
+ # lang_graph_assoc.name
171
+ # )
172
+ # return None
173
+ #
174
+ # assoc = getattr(lang_classes_factory.ns, assoc_name)()
175
+ # setattr(assoc, left_field, [left_asset])
176
+ # setattr(assoc, right_field, [right_asset])
177
+ # instance_model.add_association(assoc)
178
+ #
179
+ # return instance_model