Skip to content

Commit 15f5e0b

Browse files
author
Bryan Worrell
committed
Merge pull request #132 from STIXProject/stix1.1.1
python-stix v1.1.1.0
2 parents ff57895 + 5ca7e20 commit 15f5e0b

31 files changed

+173
-141
lines changed

CHANGES.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Version 1.1.1.0
2+
2014-05-09
3+
- Support for STIX v1.1.1
4+
- Updated all schemalocations to reference new STIX v1.1.1 schemas
5+
- Changed Confidence.source to be of type InformationSource
6+
- Changed Statement.source to be of type InformationSource
7+
- Changed Sighting.source to be of type InformationSource
8+
- Updated AvailabilityLossType CV to align with STIX v1.1.1
9+
110
Version 1.1.0.6
211
2014-05-06
312
- Fixed issues with parsing Related Observables within an Incident

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
python-stix
22
===========
33

4-
A python library for parsing, manipulating, and generating STIX content.
4+
A python library for parsing, manipulating, and generating STIX v1.1.1 content.
55

6-
The ``python-stix`` library utilizes the STIX v1.1 bindings, is under heavy
6+
The ``python-stix`` library utilizes the STIX v1.1.1 bindings, is under heavy
77
development. For more information about STIX, see http://stix.mitre.org.
88

99
.. image:: https://travis-ci.org/STIXProject/python-stix.png?branch=master

examples/ex_01.xml

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
<!--
2-
STIX IP Watchlist Example
3-
4-
Copyright (c) 2014, The MITRE Corporation. All rights reserved.
2+
STIX IP Watchlist Example
3+
4+
Copyright (c) 2014, The MITRE Corporation. All rights reserved.
55
The contents of this file are subject to the terms of the STIX License located at http://stix.mitre.org/about/termsofuse.html.
66
7-
This example demonstrates a simple usage of STIX to represent a list of IP address indicators (watchlist of IP addresses). Cyber operations and malware analysis centers often share a list of suspected malicious IP addresses with information about what those IPs might indicate. This STIX package represents a list of three IP addresses with a short dummy description of what they represent.
8-
9-
It demonstrates the use of:
10-
11-
* STIX Indicators
12-
* CybOX within STIX
13-
* The CybOX Address Object (IP)
14-
* CybOX Patterns (apply_condition="ANY")
15-
* Controlled vocabularies
16-
17-
Created by Mark Davidson
7+
This example demonstrates a simple usage of STIX to represent a list of IP address indicators (watchlist of IP addresses). Cyber operations and malware analysis centers often share a list of suspected malicious IP addresses with information about what those IPs might indicate. This STIX package represents a list of three IP addresses with a short dummy description of what they represent.
8+
9+
It demonstrates the use of:
10+
11+
* STIX Indicators
12+
* CybOX within STIX
13+
* The CybOX Address Object (IP)
14+
* CybOX Patterns (apply_condition="ANY")
15+
* Controlled vocabularies
16+
17+
Created by Mark Davidson
1818
-->
1919
<stix:STIX_Package
2020
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -26,19 +26,21 @@
2626
xmlns:stixVocabs="http://stix.mitre.org/default_vocabularies-1"
2727
xmlns:example="http://example.com/"
2828
xsi:schemaLocation="
29-
http://stix.mitre.org/stix-1 http://stix.mitre.org/XMLSchema/core/1.1/stix_core.xsd
30-
http://stix.mitre.org/Indicator-2 http://stix.mitre.org/XMLSchema/indicator/2.1/indicator.xsd
31-
http://cybox.mitre.org/default_vocabularies-2 http://cybox.mitre.org/XMLSchema/default_vocabularies/2.1/cybox_default_vocabularies.xsd
32-
http://stix.mitre.org/default_vocabularies-1 http://stix.mitre.org/XMLSchema/default_vocabularies/1.1.0/stix_default_vocabularies.xsd
33-
http://cybox.mitre.org/objects#AddressObject-2 http://cybox.mitre.org/XMLSchema/objects/Address/2.1/Address_Object.xsd"
29+
http://stix.mitre.org/stix-1 ../stix_core.xsd
30+
http://stix.mitre.org/Indicator-2 ../indicator.xsd
31+
http://cybox.mitre.org/default_vocabularies-2 ../cybox/cybox_default_vocabularies.xsd
32+
http://stix.mitre.org/default_vocabularies-1 ../stix_default_vocabularies.xsd
33+
http://cybox.mitre.org/objects#AddressObject-2 ../cybox/objects/Address_Object.xsd"
3434
id="example:STIXPackage-33fe3b22-0201-47cf-85d0-97c02164528d"
35-
version="1.1">
35+
timestamp="2014-05-08T09:00:00.000000Z"
36+
version="1.1.1"
37+
>
3638
<stix:STIX_Header>
3739
<stix:Title>Example watchlist that contains IP information.</stix:Title>
3840
<stix:Package_Intent xsi:type="stixVocabs:PackageIntentVocab-1.0">Indicators - Watchlist</stix:Package_Intent>
3941
</stix:STIX_Header>
4042
<stix:Indicators>
41-
<stix:Indicator xsi:type="indicator:IndicatorType" id="example:Indicator-33fe3b22-0201-47cf-85d0-97c02164528d">
43+
<stix:Indicator xsi:type="indicator:IndicatorType" id="example:Indicator-33fe3b22-0201-47cf-85d0-97c02164528d" timestamp="2014-05-08T09:00:00.000000Z">
4244
<indicator:Type xsi:type="stixVocabs:IndicatorTypeVocab-1.1">IP Watchlist</indicator:Type>
4345
<indicator:Description>Sample IP Address Indicator for this watchlist. This contains one indicator with a set of three IP addresses in the watchlist.</indicator:Description>
4446
<indicator:Observable id="example:Observable-1c798262-a4cd-434d-a958-884d6980c459">
@@ -51,3 +53,4 @@
5153
</stix:Indicator>
5254
</stix:Indicators>
5355
</stix:STIX_Package>
56+

stix/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (c) 2014, The MITRE Corporation. All rights reserved.
22
# See LICENSE.txt for complete terms.
33

4-
__version__ = "1.1.0.6"
4+
__version__ = "1.1.1.0"
55

66
from .base import Entity, EntityList
77

stix/base.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
# See LICENSE.txt for complete terms.
33

44
import collections
5+
import inspect
56
import json
6-
from lxml import etree
77
from StringIO import StringIO
88

9+
import cybox
10+
from cybox.core import Observable, Observables
11+
from lxml import etree
912

1013
class Entity(object):
1114
"""Base class for all classes in the STIX API."""
@@ -50,6 +53,18 @@ def to_xml(self, include_namespaces=True, ns_dict=None, pretty=True):
5053
self.to_obj().export(s, 0, all_ns_dict, pretty_print=pretty, namespacedef_=namespace_def)
5154
return s.getvalue()
5255

56+
def _get_children(self):
57+
for (name, obj) in inspect.getmembers(self):
58+
if isinstance(obj, Observables):
59+
for obs in obj.observables:
60+
yield obs
61+
elif isinstance(obj, (Entity, cybox.Entity)):
62+
yield obj
63+
elif isinstance(obj, list):
64+
for item in obj:
65+
if isinstance(item, Entity) or isinstance(item, Observable) or isinstance(item, cybox.Entity):
66+
yield item
67+
5368
def to_json(self):
5469
return json.dumps(self.to_dict())
5570

stix/bindings/incident.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,10 @@ class ContributorsType(GeneratedsSuper):
12171217
subclass = None
12181218
superclass = None
12191219
def __init__(self, Contributor=None):
1220-
self.Contributor = Contributor
1220+
if Contributor is None:
1221+
self.Contributor = []
1222+
else:
1223+
self.Contributor = Contributor
12211224
def factory(*args_, **kwargs_):
12221225
if ContributorsType.subclass:
12231226
return ContributorsType.subclass(*args_, **kwargs_)
@@ -1226,9 +1229,11 @@ def factory(*args_, **kwargs_):
12261229
factory = staticmethod(factory)
12271230
def get_Contributor(self): return self.Contributor
12281231
def set_Contributor(self, Contributor): self.Contributor = Contributor
1232+
def add_Contributor(self, value): self.Contributor.append(value)
1233+
def insert_Contributor(self, index, value): self.Contributor[index] = value
12291234
def hasContent_(self):
12301235
if (
1231-
self.Contributor is not None
1236+
self.Contributor
12321237
):
12331238
return True
12341239
else:
@@ -1256,8 +1261,8 @@ def exportChildren(self, outfile, level, nsmap, namespace_=XML_NS, name_='Contri
12561261
eol_ = '\n'
12571262
else:
12581263
eol_ = ''
1259-
if self.Contributor is not None:
1260-
self.Contributor.export(outfile, level, nsmap, namespace_, name_='Contributor', pretty_print=pretty_print)
1264+
for Contributor_ in self.Contributor:
1265+
Contributor_.export(outfile, level, "%s:" % (nsmap[namespace_]), name_='Contributor', pretty_print=pretty_print)
12611266
def build(self, node):
12621267
already_processed = set()
12631268
self.buildAttributes(node, node.attrib, already_processed)
@@ -1270,7 +1275,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
12701275
if nodeName_ == 'Contributor':
12711276
obj_ = cybox_common_binding.ContributorType.factory()
12721277
obj_.build(child_)
1273-
self.set_Contributor(obj_)
1278+
self.Contributor.append(obj_)
12741279
# end class ContributorsType
12751280

12761281
class COATimeType(GeneratedsSuper):

stix/bindings/indicator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ def buildAttributes(self, node, attrs, already_processed):
979979
self.timestamp_precision = value
980980
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
981981
if nodeName_ == 'Source':
982-
obj_ = stix_common_binding.StructuredTextType.factory()
982+
obj_ = stix_common_binding.InformationSourceType.factory()
983983
obj_.build(child_)
984984
self.set_Source(obj_)
985985
elif nodeName_ == 'Reference':
@@ -1688,7 +1688,7 @@ def buildAttributes(self, node, attrs, already_processed):
16881688
super(RelatedCampaignReferencesType, self).buildAttributes(node, attrs, already_processed)
16891689
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
16901690
if nodeName_ == 'Related_Campaign':
1691-
obj_ = stix_common_binding.CampaignReferenceType.factory()
1691+
obj_ = stix_common_binding.RelatedCampaignReferenceType.factory()
16921692
obj_.build(child_)
16931693
self.Related_Campaign.append(obj_)
16941694
super(RelatedCampaignReferencesType, self).buildChildren(child_, node, nodeName_, True)

stix/bindings/stix_common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
12131213
obj_.build(child_)
12141214
self.set_Description(obj_)
12151215
elif nodeName_ == 'Source':
1216-
obj_ = ControlledVocabularyStringType.factory()
1216+
obj_ = InformationSourceType.factory()
12171217
obj_.build(child_)
12181218
self.set_Source(obj_)
12191219
elif nodeName_ == 'Confidence_Assertion_Chain':
@@ -4037,7 +4037,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
40374037
obj_.build(child_)
40384038
self.set_Description(obj_)
40394039
elif nodeName_ == 'Source':
4040-
obj_ = ControlledVocabularyStringType.factory()
4040+
obj_ = InformationSourceType.factory()
40414041
obj_.build(child_)
40424042
self.set_Source(obj_)
40434043
elif nodeName_ == 'Confidence':

stix/campaign/__init__.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,20 @@ class RelatedTTPs(GenericRelationshipList):
6464
_contained_type = RelatedTTP
6565
_inner_name = "ttps"
6666

67-
68-
class Name(VocabString):
69-
pass
70-
71-
7267
class Names(stix.EntityList):
7368
_namespace = "http://stix.mitre.org/Campaign-1"
7469
_binding = campaign_binding
7570
_binding_class = campaign_binding.NamesType
7671
_binding_var = "Name"
77-
_contained_type = Name
72+
_contained_type = VocabString
7873
_inner_name = "names"
7974

8075

8176
class Campaign(stix.Entity):
8277
_binding = campaign_binding
8378
_binding_class = _binding.CampaignType
8479
_namespace = "http://stix.mitre.org/Campaign-1"
85-
_version = "1.1"
80+
_version = "1.1.1"
8681

8782
def __init__(self, id_=None, idref=None, timestamp=None, title=None, description=None, short_description=None):
8883
self.id_ = id_ or stix.utils.create_id("Campaign")

stix/coa/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class CourseOfAction(stix.Entity):
2929
_binding = coa_binding
3030
_binding_class = coa_binding.CourseOfActionType
3131
_namespace = "http://stix.mitre.org/CourseOfAction-1"
32-
_version = "1.1"
32+
_version = "1.1.1"
3333

3434
def __init__(self, id_=None, idref=None, timestamp=None, title=None, description=None, short_description=None):
3535
self.id_ = id_ or stix.utils.create_id("coa")

stix/common/confidence.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copyright (c) 2014, The MITRE Corporation. All rights reserved.
22
# See LICENSE.txt for complete terms.
33

4+
from __future__ import absolute_import
5+
46
from datetime import datetime
57
import dateutil
68
from dateutil.tz import tzutc
@@ -11,7 +13,6 @@
1113
from .structured_text import StructuredText
1214
from .vocabs import VocabString, HighMediumLow
1315

14-
1516
class Confidence(stix.Entity):
1617
_namespace = 'http://stix.mitre.org/common-1'
1718
_binding = common_binding
@@ -58,12 +59,14 @@ def source(self):
5859

5960
@source.setter
6061
def source(self, value):
62+
from .information_source import InformationSource
63+
6164
if value is None:
6265
self._source = None
63-
elif isinstance(value, VocabString):
66+
elif isinstance(value, InformationSource):
6467
self._source = value
6568
else:
66-
self._source = VocabString(value=value)
69+
raise ValueError("source must be of type InformationSource")
6770

6871
@property
6972
def description(self):
@@ -119,6 +122,8 @@ def to_dict(self):
119122

120123
@staticmethod
121124
def from_obj(obj):
125+
from .information_source import InformationSource
126+
122127
if not obj:
123128
return None
124129
c = Confidence()
@@ -127,12 +132,14 @@ def from_obj(obj):
127132
c.timestamp_precision = obj.get_timestamp_precision()
128133
c.value = VocabString.from_obj(obj.get_Value())
129134
c.description = StructuredText.from_obj(obj.get_Description())
130-
c.source = VocabString.from_obj(obj.get_Source())
135+
c.source = InformationSource.from_obj(obj.get_Source())
131136

132137
return c
133138

134139
@staticmethod
135140
def from_dict(dict_):
141+
from .information_source import InformationSource
142+
136143
if dict_ is None:
137144
return None
138145
c = Confidence()
@@ -141,11 +148,10 @@ def from_dict(dict_):
141148
c.timestamp_precision = dict_.get('timestamp_precision', 'second')
142149
c.value = VocabString.from_dict(dict_.get('value'))
143150
c.description = StructuredText.from_dict(dict_.get('description'))
144-
c.source = VocabString.from_dict(dict_.get('source'))
151+
c.source = InformationSource.from_dict(dict_.get('source'))
145152

146153
return c
147154

148-
149155
class ConfidenceAssertionChain(stix.Entity):
150156
_namespace = 'http://stix.mitre.org/common-2'
151157
_binding = common_binding
@@ -176,3 +182,4 @@ def to_dict(self):
176182
@classmethod
177183
def from_dict(cls, dict_repr, return_obj=None):
178184
return None
185+

stix/common/related.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55

66
import stix
77
import stix.bindings.stix_common as common_binding
8-
9-
from .confidence import Confidence
10-
from .information_source import InformationSource
118
from .vocabs import VocabString
9+
from .information_source import InformationSource
10+
from .confidence import Confidence
1211

1312
class GenericRelationship(stix.Entity):
1413
_namespace = "http://stix.mitre.org/common-1"
1514
_binding = common_binding
1615
_binding_class = common_binding.GenericRelationshipType
1716

1817
def __init__(self, confidence=None, information_source=None, relationship=None):
18+
1919
self.confidence = confidence
2020
self.information_source = information_source
2121
self.relationship = relationship

0 commit comments

Comments
 (0)