2017-04-19 20:32:56 +02:00
|
|
|
"""STIX 2.0 Objects that are neither SDOs nor SROs"""
|
2017-03-31 21:52:27 +02:00
|
|
|
|
2017-08-14 16:34:53 +02:00
|
|
|
from collections import OrderedDict
|
|
|
|
|
2017-03-31 21:52:27 +02:00
|
|
|
from .base import _STIXBase
|
2017-04-25 00:29:56 +02:00
|
|
|
from .properties import (IDProperty, ListProperty, Property, ReferenceProperty,
|
|
|
|
SelectorProperty, StringProperty, TimestampProperty,
|
|
|
|
TypeProperty)
|
2017-05-09 21:10:53 +02:00
|
|
|
from .utils import NOW, get_dict
|
2017-03-31 21:52:27 +02:00
|
|
|
|
|
|
|
|
2017-04-19 20:32:56 +02:00
|
|
|
class ExternalReference(_STIXBase):
|
2017-08-14 16:34:53 +02:00
|
|
|
_properties = OrderedDict()
|
|
|
|
_properties = _properties.update([
|
|
|
|
('source_name', StringProperty(required=True)),
|
|
|
|
('description', StringProperty()),
|
|
|
|
('url', StringProperty()),
|
|
|
|
('external_id', StringProperty()),
|
|
|
|
])
|
2017-04-14 16:42:17 +02:00
|
|
|
|
2017-05-18 15:48:01 +02:00
|
|
|
def _check_object_constraints(self):
|
|
|
|
super(ExternalReference, self)._check_object_constraints()
|
2017-05-12 19:18:02 +02:00
|
|
|
self._check_at_least_one_property(["description", "external_id", "url"])
|
|
|
|
|
2017-04-14 16:42:17 +02:00
|
|
|
|
2017-04-19 20:32:56 +02:00
|
|
|
class KillChainPhase(_STIXBase):
|
2017-08-14 16:34:53 +02:00
|
|
|
_properties = OrderedDict()
|
|
|
|
_properties = _properties.update([
|
|
|
|
('kill_chain_name', StringProperty(required=True)),
|
|
|
|
('phase_name', StringProperty(required=True)),
|
|
|
|
])
|
2017-04-19 20:32:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
class GranularMarking(_STIXBase):
|
2017-08-14 16:34:53 +02:00
|
|
|
_properties = OrderedDict()
|
|
|
|
_properties = _properties.update([
|
|
|
|
('marking_ref', ReferenceProperty(required=True, type="marking-definition")),
|
|
|
|
('selectors', ListProperty(SelectorProperty, required=True)),
|
|
|
|
])
|
2017-03-31 21:52:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TLPMarking(_STIXBase):
|
|
|
|
# TODO: don't allow the creation of any other TLPMarkings than the ones below
|
2017-08-14 16:34:53 +02:00
|
|
|
_properties = OrderedDict()
|
|
|
|
_properties = _properties.update([
|
|
|
|
('tlp', Property(required=True))
|
|
|
|
])
|
2017-03-31 21:52:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
class StatementMarking(_STIXBase):
|
2017-08-14 16:34:53 +02:00
|
|
|
_properties = OrderedDict()
|
|
|
|
_properties = _properties.update([
|
|
|
|
('statement', StringProperty(required=True))
|
|
|
|
])
|
2017-03-31 21:52:27 +02:00
|
|
|
|
|
|
|
def __init__(self, statement=None, **kwargs):
|
|
|
|
# Allow statement as positional args.
|
|
|
|
if statement and not kwargs.get('statement'):
|
|
|
|
kwargs['statement'] = statement
|
|
|
|
|
|
|
|
super(StatementMarking, self).__init__(**kwargs)
|
2017-04-19 20:32:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
class MarkingProperty(Property):
|
|
|
|
"""Represent the marking objects in the `definition` property of
|
|
|
|
marking-definition objects.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def clean(self, value):
|
|
|
|
if type(value) in [TLPMarking, StatementMarking]:
|
|
|
|
return value
|
|
|
|
else:
|
|
|
|
raise ValueError("must be a Statement or TLP Marking.")
|
|
|
|
|
|
|
|
|
|
|
|
class MarkingDefinition(_STIXBase):
|
|
|
|
_type = 'marking-definition'
|
2017-08-14 16:34:53 +02:00
|
|
|
_properties = OrderedDict()
|
|
|
|
_properties = _properties.update([
|
|
|
|
('created', TimestampProperty(default=lambda: NOW)),
|
|
|
|
('external_references', ListProperty(ExternalReference)),
|
|
|
|
('created_by_ref', ReferenceProperty(type="identity")),
|
|
|
|
('object_marking_refs', ListProperty(ReferenceProperty(type="marking-definition"))),
|
|
|
|
('granular_markings', ListProperty(GranularMarking)),
|
|
|
|
('type', TypeProperty(_type)),
|
|
|
|
('id', IDProperty(_type)),
|
|
|
|
('definition_type', StringProperty(required=True)),
|
|
|
|
('definition', MarkingProperty(required=True)),
|
|
|
|
])
|
2017-04-19 20:32:56 +02:00
|
|
|
marking_map = {
|
|
|
|
'tlp': TLPMarking,
|
|
|
|
'statement': StatementMarking,
|
|
|
|
}
|
|
|
|
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
if set(('definition_type', 'definition')).issubset(kwargs.keys()):
|
|
|
|
# Create correct marking type object
|
|
|
|
try:
|
|
|
|
marking_type = self.marking_map[kwargs['definition_type']]
|
|
|
|
except KeyError:
|
|
|
|
raise ValueError("definition_type must be a valid marking type")
|
|
|
|
|
|
|
|
if not isinstance(kwargs['definition'], marking_type):
|
|
|
|
defn = get_dict(kwargs['definition'])
|
|
|
|
kwargs['definition'] = marking_type(**defn)
|
|
|
|
|
|
|
|
super(MarkingDefinition, self).__init__(**kwargs)
|
2017-03-31 21:52:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
TLP_WHITE = MarkingDefinition(
|
2017-08-14 16:36:47 +02:00
|
|
|
id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
|
|
|
|
created="2017-01-20T00:00:00.000Z",
|
|
|
|
definition_type="tlp",
|
|
|
|
definition=TLPMarking(tlp="white")
|
2017-03-31 21:52:27 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
TLP_GREEN = MarkingDefinition(
|
2017-08-14 16:36:47 +02:00
|
|
|
id="marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",
|
|
|
|
created="2017-01-20T00:00:00.000Z",
|
|
|
|
definition_type="tlp",
|
|
|
|
definition=TLPMarking(tlp="green")
|
2017-03-31 21:52:27 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
TLP_AMBER = MarkingDefinition(
|
2017-08-14 16:36:47 +02:00
|
|
|
id="marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",
|
|
|
|
created="2017-01-20T00:00:00.000Z",
|
|
|
|
definition_type="tlp",
|
|
|
|
definition=TLPMarking(tlp="amber")
|
2017-03-31 21:52:27 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
TLP_RED = MarkingDefinition(
|
2017-08-14 16:36:47 +02:00
|
|
|
id="marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed",
|
|
|
|
created="2017-01-20T00:00:00.000Z",
|
|
|
|
definition_type="tlp",
|
|
|
|
definition=TLPMarking(tlp="red")
|
2017-03-31 21:52:27 +02:00
|
|
|
)
|