diff --git a/.gitignore b/.gitignore
index 6061b3c..a04a143 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ dist/
*.egg-info
.settings/
.project
+.idea
.pydevproject
.tox
diff --git a/.travis.yml b/.travis.yml
index 87517cb..e99e66d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,27 +1,19 @@
+os: linux
language: python
-
+cache: pip
+dist: xenial
python:
- - 3.5
-
-env:
- - TOXENV=py26
- - TOXENV=py27
- - TOXENV=py33
- - TOXENV=py34
- - TOXENV=py35
- - TOXENV=rhel6
-
+ - "2.7"
+ - "3.4"
+ - "3.5"
+ - "3.6"
+ - "3.7"
+ - "3.8"
install:
- - pip install -U tox
-
+ - pip install -U pip setuptools
+ - pip install tox-travis
script:
- tox
-
-branches:
- only:
- - master
-
notifications:
email:
- - gback@mitre.org
- - stix-commits-list@lists.mitre.org
+ - stix-commits-list@groups.mitre.org
diff --git a/CHANGES.txt b/CHANGES.txt
index 51c740a..6c2de9a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,22 @@
+Version 4.1.0.17
+2020-11-16
+- Remove deprecation warning for collections module
+
+Version 4.1.0.16
+2019-09-17
+- [#96] Fix problem when installing from Python 2.7
+
+Version 4.1.0.15
+2019-09-06
+- Update project requirements
+
+Version 4.1.0.14
+2018-08-03
+- Drop support for Python 2.6, 3.3
+- [#91] Don't duplicate Action Collections (@jtschichold)
+- [#93] Handle non-ASCII characters in README (@colbyprior)
+- Various packaging, testing, and other non-functional improvements
+
Version 4.1.0.13
2016-08-09
- Add support for Python 3.3+
diff --git a/LICENSE.txt b/LICENSE.txt
index fdf626e..a7dd435 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2015, The MITRE Corporation
+Copyright (c) 2018, The MITRE Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -8,7 +8,7 @@ modification, are permitted provided that the following conditions are met:
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- * Neither the name of The MITRE Corporation nor the
+ * Neither the name of The MITRE Corporation nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
diff --git a/README.rst b/README.rst
index 9a921b6..2ef5d63 100644
--- a/README.rst
+++ b/README.rst
@@ -1,10 +1,10 @@
python-maec
===========
-A Python library for parsing, manipulating, and generating `Malware Attribute Enumeration and Characterization (MAEC™) `_ content.
+A Python library for parsing, manipulating, and generating `Malware Attribute Enumeration and Characterization (MAEC™) `_ v4.1 content.
:Source: https://github.com/MAECProject/python-maec
-:Documentation: http://maec.readthedocs.org
+:Documentation: https://maec.readthedocs.io/
:Information: https://maecproject.github.io/
:Download: https://pypi.python.org/pypi/maec/
@@ -12,10 +12,10 @@ A Python library for parsing, manipulating, and generating `Malware Attribute En
.. |travis badge| image:: https://api.travis-ci.org/MAECProject/python-maec.svg?branch=master
:target: https://travis-ci.org/MAECProject/python-maec
- :alt: Build Status
+ :alt: Build Status
.. |landscape.io badge| image:: https://landscape.io/github/MAECProject/python-maec/master/landscape.svg?style=flat
:target: https://landscape.io/github/MAECProject/python-maec/master
- :alt: Code Health
+ :alt: Code Health
.. |Version Badge| image:: https://img.shields.io/pypi/v/maec.svg?maxAge=3600
:target: https://pypi.python.org/pypi/maec/
.. |Downloads Badge| image:: https://img.shields.io/pypi/dm/maec.svg?maxAge=3600
@@ -49,7 +49,7 @@ There are currently two levels of APIs for dealing with MAEC content:
Compatibility
-------------
-The python-maec library is tested and written against python ``2.6, 2.7, and 3.3+``. Compatibility with other python versions is neither guaranteed nor implied.
+The python-maec library is tested against Python 2.7 and 3.4+.
Versioning
----------
@@ -76,7 +76,7 @@ The python-maec library is also hosted on `PyPI
Dependencies
------------
-The ``maec`` package depends on the following Python libraries:
+The ``maec`` package depends on the following Python libraries:
* ``lxml``
diff --git a/docs/conf.py b/docs/conf.py
index ab8d807..37ffa6e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,9 +1,10 @@
+import doctest
import os
import maec
project = u'python-maec'
-copyright = u'2014, The MITRE Corporation'
+copyright = u'2018, The MITRE Corporation'
version = maec.__version__
release = version
@@ -11,15 +12,10 @@
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.ifconfig',
- 'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
]
-intersphinx_mapping = {
- 'python': ('http://docs.python.org/', None),
-}
-
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
@@ -46,3 +42,5 @@
('index', 'python-maec.tex', u'python-maec Documentation',
u'The MITRE Corporation', 'manual'),
]
+
+doctest_default_flags = doctest.NORMALIZE_WHITESPACE
\ No newline at end of file
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index ed5570e..069c224 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -23,7 +23,7 @@ Once you have installed python-maec, you can begin writing Python applications t
.. note::
- The *python-maec* library provides **bindings** and **APIs**, both of which can be used to parse and write MAEC XML files. For in-depth description of the *APIs, bindings, and the differences between the two*, please refer to :doc:`api_vs_bindings/index`
+ The *python-maec* library provides **bindings** and **APIs**, both of which can be used to parse and write MAEC XML files. For in-depth description of the *APIs, bindings, and the differences between the two*, please refer to :doc:`api_vs_bindings/index`
Creating a MAEC Package
***********************
diff --git a/docs/index.rst b/docs/index.rst
index f667181..47a49af 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -15,13 +15,13 @@ version of MAEC.
============ ===================
MAEC Version python-maec Version
============ ===================
-4.1 4.1.0.12 (`PyPI`__) (`GitHub`__)
+4.1 4.1.0.17 (`PyPI`__) (`GitHub`__)
4.0 4.0.1.0 (`PyPI`__) (`GitHub`__)
3.0 3.0.0b1 (`PyPI`__) (`GitHub`__)
============ ===================
-__ https://pypi.python.org/pypi/maec/4.1.0.12
-__ https://github.com/MAECProject/python-maec/tree/v4.1.0.12
+__ https://pypi.python.org/pypi/maec/4.1.0.17
+__ https://github.com/MAECProject/python-maec/tree/v4.1.0.17
__ https://pypi.python.org/pypi/maec/4.0.1.0
__ https://github.com/MAECProject/python-maec/tree/v4.0.1.0
__ https://pypi.python.org/pypi/maec/3.0.0b1
diff --git a/maec/__init__.py b/maec/__init__.py
index beece9b..2ad2570 100644
--- a/maec/__init__.py
+++ b/maec/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
from __future__ import absolute_import
@@ -29,7 +29,7 @@ def _ns_to_prefix_input_namespaces(self):
def to_xml_file(self, file, namespace_dict=None, custom_header=None):
"""Export an object to an XML file. Only supports Package or Bundle
objects at the moment.
-
+
Args:
file: the name of a file or a file-like object to write the output to.
namespace_dict: a dictionary of mappings of additional XML namespaces to
diff --git a/maec/analytics/distance.py b/maec/analytics/distance.py
index 12dff90..53609b2 100644
--- a/maec/analytics/distance.py
+++ b/maec/analytics/distance.py
@@ -1,5 +1,5 @@
# MAEC Distance Measure-related Classes - BETA
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
# See LICENSE.txt for complete terms
@@ -139,7 +139,7 @@ def create_object_vector(self, object, static_feature_dict, callback_function =
# Callback function parameters : feature name, existing feature value, new feature value
elif callback_function:
existing_value = static_feature_dict[feature_name]
- static_feature_dict[feature_name] = callback_function(feature_name, existing_value, feature_value)
+ static_feature_dict[feature_name] = callback_function(feature_name, existing_value, feature_value)
else:
static_feature_dict[feature_name] = feature_value
@@ -251,7 +251,7 @@ def bin_list(self, numeric_value, numeric_list, n=10):
return bin_vector
max_list = max(numeric_list)
min_list = min(numeric_list)
- bucket_size = (max_list-min_list)/n
+ bucket_size = (max_list-min_list)/n
bin_value = int(math.floor((numeric_value - min_list)/bucket_size))
if bin_value == n:
bin_value -= 1
@@ -455,7 +455,7 @@ def create_static_result_vector(self, static_vector):
bin = self.bin_list(normalized_value, normalized_items, feature_options_dict['number of bins'])
else:
bin = self.bin_list(normalized_value, normalized_items)
- results_vector.append(bin)
+ results_vector.append(bin)
elif normalized_value is not None:
results_vector.append(normalized_value)
else:
@@ -580,7 +580,7 @@ def calculate(self):
self.perform_calculation()
def print_distances(self, file_object, default_label = 'md5', delimiter = ','):
- '''Print the distances between the Malware Subjects in delimited matrix format
+ '''Print the distances between the Malware Subjects in delimited matrix format
to a File-like object.
Try to use the MD5s of the Malware Subjects as the default label.
@@ -611,5 +611,3 @@ def print_distances(self, file_object, default_label = 'md5', delimiter = ','):
for distance_string in distance_strings:
file_object.write(distance_string + "\n")
file_object.flush()
-
-
diff --git a/maec/analytics/static_features.py b/maec/analytics/static_features.py
index 04f8f03..e95ace8 100644
--- a/maec/analytics/static_features.py
+++ b/maec/analytics/static_features.py
@@ -1,5 +1,5 @@
# MAEC Static Features List
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
static_features_dict = {'file_name' : {'feature_name' : 'file_name'},
diff --git a/maec/bindings/maec_bundle.py b/maec/bindings/maec_bundle.py
index 58782ee..36af803 100644
--- a/maec/bindings/maec_bundle.py
+++ b/maec/bindings/maec_bundle.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import sys
diff --git a/maec/bindings/maec_container.py b/maec/bindings/maec_container.py
index e80b145..dfe855c 100644
--- a/maec/bindings/maec_container.py
+++ b/maec/bindings/maec_container.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import sys
@@ -266,5 +266,5 @@ def main():
GDSClassesMapping = {
"ContainerType": ContainerType,
- "PackageListType": PackageListType
+ "PackageListType": PackageListType
}
diff --git a/maec/bindings/maec_package.py b/maec/bindings/maec_package.py
index a26ba3d..a87e803 100644
--- a/maec/bindings/maec_package.py
+++ b/maec/bindings/maec_package.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import sys
@@ -1012,7 +1012,7 @@ def __init__(self, id=None, Malware_Instance_Object_Attributes=None, Label=None,
self.Malware_Instance_Object_Attributes = Malware_Instance_Object_Attributes
self.Configuration_Details = Configuration_Details
self.Minor_Variants = Minor_Variants
- self.Development_Environment = Development_Environment
+ self.Development_Environment = Development_Environment
self.Field_Data = Field_Data
self.Analyses = Analyses
self.Findings_Bundles = Findings_Bundles
diff --git a/maec/bindings/mmdef_1_2.py b/maec/bindings/mmdef_1_2.py
index 3613975..b70d006 100644
--- a/maec/bindings/mmdef_1_2.py
+++ b/maec/bindings/mmdef_1_2.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import sys
@@ -3256,7 +3256,7 @@ def parse(inFileName):
# Enable Python to collect the space used by the DOM.
doc = None
sys.stdout.write('\n')
- rootObj.export(sys.stdout, 0, name_=rootTag,
+ rootObj.export(sys.stdout, 0, name_=rootTag,
namespacedef_='')
return rootObj
diff --git a/maec/bundle/action_reference_list.py b/maec/bundle/action_reference_list.py
index aaf604a..99f417e 100644
--- a/maec/bundle/action_reference_list.py
+++ b/maec/bundle/action_reference_list.py
@@ -1,6 +1,6 @@
#MAEC Action Reference List Class
-#Copyright (c) 2015, The MITRE Corporation
+#Copyright (c) 2018, The MITRE Corporation
#All rights reserved
from cybox.core import ActionReference
diff --git a/maec/bundle/av_classification.py b/maec/bundle/av_classification.py
index f83700a..1148303 100644
--- a/maec/bundle/av_classification.py
+++ b/maec/bundle/av_classification.py
@@ -1,5 +1,5 @@
# MAEC AV Classification classes
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from cybox.common import ToolInformation
@@ -25,9 +25,9 @@ def to_obj(self, ns_info=None):
obj = super(AVClassification, self).to_obj(ns_info=ns_info)
if self.engine_version is not None :
obj.Engine_Version = self.engine_version
- if self.definition_version is not None :
+ if self.definition_version is not None :
obj.Definition_Version = self.definition_version
- if self.classification_name is not None :
+ if self.classification_name is not None :
obj.Classification_Name = self.classification_name
return obj
diff --git a/maec/bundle/behavior.py b/maec/bundle/behavior.py
index 07881a3..b4dc62e 100644
--- a/maec/bundle/behavior.py
+++ b/maec/bundle/behavior.py
@@ -1,6 +1,6 @@
# MAEC Behavior Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -16,7 +16,7 @@
class BehavioralActionEquivalenceReference(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.BehavioralActionEquivalenceReferenceType
+ _binding_class = bundle_binding.BehavioralActionEquivalenceReferenceType
_namespace = _namespace
action_equivalence_idref = fields.TypedField('action_equivalence_idref')
@@ -24,21 +24,21 @@ class BehavioralActionEquivalenceReference(maec.Entity):
class BehavioralActionReference(ActionReference):
_binding = bundle_binding
- _binding_class = bundle_binding.BehavioralActionReferenceType
+ _binding_class = bundle_binding.BehavioralActionReferenceType
_namespace = _namespace
behavioral_ordering = fields.TypedField('behavioral_ordering')
class BehavioralAction(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.BehavioralActionType
+ _binding_class = bundle_binding.BehavioralActionType
_namespace = _namespace
behavioral_ordering = fields.TypedField('behavioral_ordering')
class BehavioralActions(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.BehavioralActionsType
+ _binding_class = bundle_binding.BehavioralActionsType
_namespace = _namespace
#TODO: action_collection.type_ is set below to avoid circular import.
@@ -55,7 +55,7 @@ class PlatformList(maec.EntityList):
class CVEVulnerability(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.CVEVulnerabilityType
+ _binding_class = bundle_binding.CVEVulnerabilityType
_namespace = _namespace
cve_id = fields.TypedField('cve_id')
@@ -63,9 +63,9 @@ class CVEVulnerability(maec.Entity):
class Exploit(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.ExploitType
+ _binding_class = bundle_binding.ExploitType
_namespace = _namespace
-
+
known_vulnerability = fields.TypedField('known_vulnerability')
cve = fields.TypedField('CVE', CVEVulnerability)
cwe_id = fields.TypedField('CWE_ID', multiple=True)
@@ -73,7 +73,7 @@ class Exploit(maec.Entity):
class BehaviorPurpose(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.BehaviorPurposeType
+ _binding_class = bundle_binding.BehaviorPurposeType
_namespace = _namespace
description = fields.TypedField('Description')
@@ -81,13 +81,13 @@ class BehaviorPurpose(maec.Entity):
class AssociatedCode(maec.EntityList):
_binding = bundle_binding
- _binding_class = bundle_binding.AssociatedCodeType
+ _binding_class = bundle_binding.AssociatedCodeType
_namespace = _namespace
code_snippet = fields.TypedField("Code_Snippet", Code, multiple=True)
class Behavior(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.BehaviorType
+ _binding_class = bundle_binding.BehaviorType
_namespace = _namespace
id_ = fields.TypedField('id')
diff --git a/maec/bundle/behavior_reference.py b/maec/bundle/behavior_reference.py
index 3c74a15..c9eca18 100644
--- a/maec/bundle/behavior_reference.py
+++ b/maec/bundle/behavior_reference.py
@@ -1,6 +1,6 @@
# MAEC Behavior Reference Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -8,10 +8,10 @@
import maec
from . import _namespace
import maec.bindings.maec_bundle as bundle_binding
-
+
class BehaviorReference(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.BehaviorReferenceType
+ _binding_class = bundle_binding.BehaviorReferenceType
_namespace = _namespace
behavior_idref = fields.TypedField("behavior_idref")
diff --git a/maec/bundle/bundle.py b/maec/bundle/bundle.py
index 164ce12..f4aad2a 100644
--- a/maec/bundle/bundle.py
+++ b/maec/bundle/bundle.py
@@ -1,6 +1,6 @@
# MAEC Bundle Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -32,7 +32,7 @@ class ActionList(maec.EntityList):
_binding_class = bundle_binding.ActionListType
_namespace = _namespace
action = fields.TypedField("Action", MalwareAction, multiple=True)
-
+
class ObjectList(maec.EntityList):
_binding_class = bundle_binding.ObjectListType
@@ -181,6 +181,7 @@ def __init__(self):
def to_obj(self, ns_info=None):
action_collection_list_obj = super(ActionCollectionList, self).to_obj()
+ action_collection_list_obj.set_Action_Collection([])
for action_collection in self:
if len(action_collection.action_list) > 0:
@@ -385,9 +386,9 @@ def add_named_action_collection(self, collection_name, collection_id = None):
self.collections = Collections()
if collection_name is not None:
self.collections.add_named_action_collection(collection_name, collection_id)
-
+
def add_action(self, action, action_collection_name = None):
- """Add an Action to an existing named Action Collection in the Collections entity.
+ """Add an Action to an existing named Action Collection in the Collections entity.
If it does not exist, add it to the top-level Actions entity."""
if action_collection_name is not None and self.collections:
#The collection has already been defined
@@ -405,7 +406,7 @@ def add_named_object_collection(self, collection_name, collection_id = None):
self.collections = Collections()
if collection_name is not None:
self.collections.add_named_object_collection(collection_name, collection_id)
-
+
def get_all_actions(self, bin = False):
"""Return a list of all Actions in the Bundle."""
all_actions = []
@@ -413,7 +414,7 @@ def get_all_actions(self, bin = False):
if self.actions:
for action in self.actions:
all_actions.append(action)
-
+
if self.collections and self.collections.action_collections:
for collection in self.collections.action_collections:
for action in collection.action_list:
@@ -445,7 +446,7 @@ def get_all_actions_on_object(self, object):
return object_actions
def add_object(self, object, object_collection_name = None):
- """Add an Object to an existing named Object Collection in the Collections entity.
+ """Add an Object to an existing named Object Collection in the Collections entity.
If it does not exist, add it to the top-level Object entity."""
if object_collection_name is not None and self.collections:
#The collection has already been defined
@@ -467,7 +468,7 @@ def get_all_objects(self, include_actions = False):
if obj.related_objects:
for related_obj in obj.related_objects:
all_objects.append(related_obj)
-
+
if self.collections and self.collections.object_collections:
for collection in self.collections.object_collections:
for obj in collection.object_list:
@@ -509,7 +510,7 @@ def get_object_by_id(self, id, extra_objects = [], ignore_actions = False):
for action in self.actions:
if action.id_ == id:
return action
-
+
if action.associated_objects:
for associated_obj in action.associated_objects:
if associated_obj.id_ == id:
@@ -519,7 +520,7 @@ def get_object_by_id(self, id, extra_objects = [], ignore_actions = False):
for action in collection.action_list:
if action.id_ == id:
return action
-
+
if action.associated_objects:
for associated_obj in action.associated_objects:
if associated_obj.id_ == id:
@@ -529,7 +530,7 @@ def get_object_by_id(self, id, extra_objects = [], ignore_actions = False):
if obj.id_ == id:
return obj
- if self.collections and self.collections.object_collections:
+ if self.collections and self.collections.object_collections:
for collection in self.collections.object_collections:
for obj in collection.object_list:
if obj.id_ == id:
@@ -548,7 +549,7 @@ def add_named_behavior_collection(self, collection_name, collection_id = None):
self.collections.add_named_behavior_collection(collection_name, collection_id)
def add_behavior(self, behavior, behavior_collection_name = None):
- """Add a Behavior to an existing named Behavior Collection in the Collections entity.
+ """Add a Behavior to an existing named Behavior Collection in the Collections entity.
If it does not exist, add it to the top-level Behaviors entity."""
if behavior_collection_name is not None and self.collections:
#The collection has already been defined
@@ -568,7 +569,7 @@ def add_named_candidate_indicator_collection(self, collection_name, collection_i
self.collections.add_named_candidate_indicator_collection(collection_name, collection_id)
def add_candidate_indicator(self, candidate_indicator, candidate_indicator_collection_name = None):
- """Add a Candidate Indicator to an existing named Candidate Indicator Collection in the Collections entity.
+ """Add a Candidate Indicator to an existing named Candidate Indicator Collection in the Collections entity.
If it does not exist, add it to the top-level Candidate Indicators entity."""
if candidate_indicator_collection_name is not None and self.collections:
#The collection has already been defined
@@ -579,9 +580,9 @@ def add_candidate_indicator(self, candidate_indicator, candidate_indicator_colle
if not self.candidate_indicators:
self.candidate_indicators = CandidateIndicatorList()
self.candidate_indicators.append(candidate_indicator)
-
+
def deduplicate(self):
- """Deduplicate all Objects in the Bundle.
+ """Deduplicate all Objects in the Bundle.
Add duplicate Objects to new "Deduplicated Objects" Object Collection,
and replace duplicate entries with references to corresponding Object."""
BundleDeduplicator.deduplicate(self)
diff --git a/maec/bundle/bundle_reference.py b/maec/bundle/bundle_reference.py
index 3fa97f0..fc1806e 100644
--- a/maec/bundle/bundle_reference.py
+++ b/maec/bundle/bundle_reference.py
@@ -1,6 +1,6 @@
#MAEC Bundle Reference Class
-#Copyright (c) 2015, The MITRE Corporation
+#Copyright (c) 2018, The MITRE Corporation
#All rights reserved
from mixbox import fields
@@ -8,7 +8,7 @@
import maec
from . import _namespace
import maec.bindings.maec_bundle as bundle_binding
-
+
class BundleReference(maec.Entity):
_namespace = _namespace
_binding = bundle_binding
@@ -19,4 +19,3 @@ class BundleReference(maec.Entity):
def __init__(self, bundle_idref = None):
super(BundleReference, self).__init__()
self.bundle_idref = bundle_idref
-
diff --git a/maec/bundle/candidate_indicator.py b/maec/bundle/candidate_indicator.py
index b95cc56..5c23574 100644
--- a/maec/bundle/candidate_indicator.py
+++ b/maec/bundle/candidate_indicator.py
@@ -1,6 +1,6 @@
# MAEC Candidate Indicator Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -15,7 +15,7 @@
class MalwareEntity(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.MalwareEntityType
+ _binding_class = bundle_binding.MalwareEntityType
_namespace = _namespace
type_ = fields.TypedField("Type", VocabString)
@@ -27,7 +27,7 @@ def __init__(self):
class CandidateIndicatorComposition(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.CandidateIndicatorCompositionType
+ _binding_class = bundle_binding.CandidateIndicatorCompositionType
_namespace = _namespace
operator = fields.TypedField("operator")
@@ -44,7 +44,7 @@ def __init__(self):
class CandidateIndicator(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.CandidateIndicatorType
+ _binding_class = bundle_binding.CandidateIndicatorType
_namespace = _namespace
id_ = fields.TypedField("id")
diff --git a/maec/bundle/capability.py b/maec/bundle/capability.py
index 47bc6eb..86a9ac9 100644
--- a/maec/bundle/capability.py
+++ b/maec/bundle/capability.py
@@ -1,6 +1,6 @@
# MAEC Capability Classes
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
diff --git a/maec/bundle/malware_action.py b/maec/bundle/malware_action.py
index a9d09f5..5500841 100644
--- a/maec/bundle/malware_action.py
+++ b/maec/bundle/malware_action.py
@@ -1,6 +1,6 @@
# MAEC Malware Action Classes
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
diff --git a/maec/bundle/object_history.py b/maec/bundle/object_history.py
index df56ddf..c6a7706 100644
--- a/maec/bundle/object_history.py
+++ b/maec/bundle/object_history.py
@@ -1,6 +1,6 @@
# MAEC Object History Classes
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
class ObjectHistory(object):
diff --git a/maec/bundle/object_reference.py b/maec/bundle/object_reference.py
index dbf9dcd..b085977 100644
--- a/maec/bundle/object_reference.py
+++ b/maec/bundle/object_reference.py
@@ -1,13 +1,13 @@
# MAEC Object Reference Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
import maec
from . import _namespace
-import maec.bindings.maec_bundle as bundle_binding
+import maec.bindings.maec_bundle as bundle_binding
class ObjectReference(maec.Entity):
_binding = bundle_binding
@@ -17,7 +17,7 @@ class ObjectReference(maec.Entity):
def __init__(self, object_idref = None):
super(ObjectReference, self).__init__()
self.object_idref = object_idref
-
+
class ObjectReferenceList(maec.EntityList):
_binding_class = bundle_binding.ObjectReferenceListType
_namespace = _namespace
diff --git a/maec/bundle/process_tree.py b/maec/bundle/process_tree.py
index f99599b..c854e63 100644
--- a/maec/bundle/process_tree.py
+++ b/maec/bundle/process_tree.py
@@ -1,6 +1,6 @@
# MAEC Process Tree classes
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -110,7 +110,7 @@ def set_parent_action(self, parent_action_id):
class ProcessTree(maec.Entity):
_binding = bundle_binding
- _binding_class = bundle_binding.ProcessTreeType
+ _binding_class = bundle_binding.ProcessTreeType
_namespace = _namespace
root_process = fields.TypedField("Root_Process", ProcessTreeNode)
diff --git a/maec/package/action_equivalence.py b/maec/package/action_equivalence.py
index f9513bb..e467fe0 100644
--- a/maec/package/action_equivalence.py
+++ b/maec/package/action_equivalence.py
@@ -1,6 +1,6 @@
#MAEC Action Equivalence Class
-#Copyright (c) 2015, The MITRE Corporation
+#Copyright (c) 2018, The MITRE Corporation
#All rights reserved
from mixbox import fields
diff --git a/maec/package/analysis.py b/maec/package/analysis.py
index 9905e97..d8e6a17 100644
--- a/maec/package/analysis.py
+++ b/maec/package/analysis.py
@@ -1,6 +1,6 @@
# MAEC Analysis Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -25,7 +25,7 @@ class Source(maec.Entity):
reference = fields.TypedField("Reference")
organization = fields.TypedField("Organization")
url = fields.TypedField("URL")
-
+
def __init__(self):
super(Source, self).__init__()
@@ -44,9 +44,9 @@ def __init__(self, value=None):
def is_plain(self):
"""Whether this can be represented as a string rather than a dictionary
"""
- return (super(Comment, self).is_plain() and
+ return (super(Comment, self).is_plain() and
self.author is None and
- self.timestamp is None and
+ self.timestamp is None and
self.observation_name is None)
def to_obj(self, ns_info=None):
@@ -123,7 +123,7 @@ class DynamicAnalysisMetadata(maec.Entity):
analysis_duration = fields.TypedField("Analysis_Duration")
exit_code = fields.TypedField("Exit_Code")
#raised_exception = fields.TypedField("Raised_Exception", MalwareException)
-
+
def __init__(self):
super(DynamicAnalysisMetadata, self).__init__()
@@ -136,12 +136,12 @@ class HypervisorHostSystem(System):
def __init__(self):
super(HypervisorHostSystem, self).__init__()
-
+
class InstalledPrograms(maec.EntityList):
_binding_class = package_binding.InstalledProgramsType
_namespace = _namespace
program = fields.TypedField("Program", PlatformSpecification, multiple=True)
-
+
class AnalysisSystem(System):
_binding = package_binding
_binding_class = package_binding.AnalysisSystemType
@@ -235,18 +235,9 @@ def __init__(self, id = None, method = None, type = None, findings_bundle_refere
# set the findings_bundle_reference values; accepts a list of bundle ID values
def set_findings_bundle(self, bundle_id):
self.findings_bundle_reference = [BundleReference.from_dict({'bundle_idref' : bundle_id})]
-
+
# add a tool to this Anaysis's ToolList
def add_tool(self, tool):
if not self.tools:
self.tools = ToolList()
self.tools.append(tool)
-
-
-
-
-
-
-
-
-
diff --git a/maec/package/grouping_relationship.py b/maec/package/grouping_relationship.py
index ea1aaf2..2e29813 100644
--- a/maec/package/grouping_relationship.py
+++ b/maec/package/grouping_relationship.py
@@ -1,13 +1,13 @@
# MAEC Grouping Relationship Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
import maec
from . import _namespace
-import maec.bindings.maec_package as package_binding
+import maec.bindings.maec_package as package_binding
from maec.package.malware_subject_reference import MalwareSubjectReference
from cybox.common import vocabs
from maec.vocabs.vocabs import GroupingRelationship as GroupingRelationshipVocab
@@ -16,7 +16,7 @@ class ClusterEdgeNodePair(maec.Entity):
_binding = package_binding
_binding_class = package_binding.ClusterEdgeNodePairType
_namespace = _namespace
-
+
similarity_index = fields.TypedField("similarity_index")
similarity_distance = fields.TypedField("similarity_distance")
malware_subject_node_a = fields.TypedField("Malware_Subject_Node_A", MalwareSubjectReference)
@@ -29,7 +29,7 @@ class ClusterComposition(maec.Entity):
_binding = package_binding
_binding_class = package_binding.ClusterCompositionType
_namespace = _namespace
-
+
score_type = fields.TypedField("score_type")
edge_node_pair = fields.TypedField("Edge_Node_Pair", ClusterEdgeNodePair, multiple=True)
@@ -79,7 +79,3 @@ class GroupingRelationshipList(maec.EntityList):
_binding_class = package_binding.GroupingRelationshipListType
_namespace = _namespace
grouping_relationship = fields.TypedField("Grouping_Relationship", GroupingRelationship, multiple=True)
-
-
-
-
diff --git a/maec/package/malware_subject.py b/maec/package/malware_subject.py
index 7115aa4..9938285 100644
--- a/maec/package/malware_subject.py
+++ b/maec/package/malware_subject.py
@@ -1,6 +1,6 @@
# MAEC Malware Subject Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -15,7 +15,7 @@
from . import _namespace
import maec.bindings.maec_package as package_binding
from maec.bundle import Bundle
-from maec.package import (ActionEquivalenceList, Analysis,
+from maec.package import (ActionEquivalenceList, Analysis,
MalwareSubjectReference, ObjectEquivalenceList)
from maec.vocabs.vocabs import MalwareLabel
from maec.vocabs.vocabs import MalwareConfigurationParameter as MalwareConfigParameterVocab
@@ -25,7 +25,7 @@ class MinorVariants(maec.EntityList):
_binding_class = package_binding.MinorVariantListType
_namespace = _namespace
minor_variant = fields.TypedField("Minor_Variant", Object, multiple=True)
-
+
class Analyses(maec.EntityList):
_binding_class = package_binding.AnalysisListType
_namespace = _namespace
@@ -235,11 +235,10 @@ def normalize_bundles(self):
all_bundles = self.get_all_bundles()
for bundle in all_bundles:
bundle.normalize_objects()
-
+
class MalwareSubjectList(maec.EntityList):
_binding_class = package_binding.MalwareSubjectListType
#_binding_var = "Malware_Subject"
_namespace = _namespace
-
+
malware_subject = fields.TypedField("Malware_Subject", MalwareSubject, multiple=True)
-
\ No newline at end of file
diff --git a/maec/package/malware_subject_reference.py b/maec/package/malware_subject_reference.py
index de3b897..aadaf1d 100644
--- a/maec/package/malware_subject_reference.py
+++ b/maec/package/malware_subject_reference.py
@@ -1,6 +1,6 @@
# MAEC Malware Subject Reference Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
diff --git a/maec/package/object_equivalence.py b/maec/package/object_equivalence.py
index 78135c1..12a44d4 100644
--- a/maec/package/object_equivalence.py
+++ b/maec/package/object_equivalence.py
@@ -1,6 +1,6 @@
# MAEC Action Equivalence Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -8,7 +8,7 @@
import maec
from . import _namespace
import maec.bindings.maec_package as package_binding
-from maec.bundle import ObjectReference
+from maec.bundle import ObjectReference
class ObjectEquivalence(maec.Entity):
_binding = package_binding
diff --git a/maec/package/package.py b/maec/package/package.py
index 2337587..9fa8119 100644
--- a/maec/package/package.py
+++ b/maec/package/package.py
@@ -1,6 +1,6 @@
# MAEC Package Class
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
from mixbox import fields
@@ -14,7 +14,7 @@
class Package(maec.Entity):
_binding = package_binding
_binding_class = package_binding.PackageType
- _namespace = _namespace
+ _namespace = _namespace
id_ = fields.TypedField('id')
timestamp = fields.TypedField('timestamp')
@@ -38,7 +38,7 @@ def __init__(self, id = None, schema_version = "2.1", timestamp = None):
#Add a malware subject to this Package
def add_malware_subject(self, malware_subject):
self.malware_subjects.append(malware_subject)
-
+
#Add a grouping relationship
def add_grouping_relationship(self, grouping_relationship):
if not self.grouping_relationships:
@@ -59,7 +59,7 @@ def from_xml(xml_file):
parser = EntityParser()
maec_package = parser.parse_xml(xml_file)
maec_package_obj = maec_package.to_obj()
-
+
return (maec_package, maec_package_obj)
# Transform duplicate objects within this Package into references pointing to a single canonical object
@@ -67,6 +67,3 @@ def deduplicate_malware_subjects(self):
"""DeDuplicate all Malware_Subjects in the Package. For now, only handles Objects in Findings Bundles"""
for malware_subject in self.malware_subjects:
malware_subject.deduplicate_bundles()
-
-
-
diff --git a/maec/test/bundle/av_classification_test.py b/maec/test/bundle/av_classification_test.py
index 9ce1e9d..3c34a03 100644
--- a/maec/test/bundle/av_classification_test.py
+++ b/maec/test/bundle/av_classification_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
diff --git a/maec/test/bundle/behavior_test.py b/maec/test/bundle/behavior_test.py
index 36d95ba..ebbf3e7 100644
--- a/maec/test/bundle/behavior_test.py
+++ b/maec/test/bundle/behavior_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
diff --git a/maec/test/bundle/bundle_test.py b/maec/test/bundle/bundle_test.py
index 898bc8a..04e01fd 100644
--- a/maec/test/bundle/bundle_test.py
+++ b/maec/test/bundle/bundle_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
diff --git a/maec/test/bundle/capability_test.py b/maec/test/bundle/capability_test.py
index ff2d139..1efe5ca 100644
--- a/maec/test/bundle/capability_test.py
+++ b/maec/test/bundle/capability_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
diff --git a/maec/test/bundle/process_tree_test.py b/maec/test/bundle/process_tree_test.py
index ee5016d..a52f625 100644
--- a/maec/test/bundle/process_tree_test.py
+++ b/maec/test/bundle/process_tree_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
@@ -43,13 +43,13 @@ def test_round_trip(self):
spawned_child2 = ProcessTreeNode()
injected_child = ProcessTreeNode()
spawned_grandchild = ProcessTreeNode()
-
+
o.set_root_process(root)
root.add_spawned_process(spawned_child1)
root.add_spawned_process(spawned_child2)
root.add_injected_process(injected_child)
spawned_child1.add_spawned_process(spawned_grandchild)
-
+
o2 = round_trip(o, True)
self.assertEqual(o.to_dict(), o2.to_dict())
diff --git a/maec/test/encoding_test.py b/maec/test/encoding_test.py
index 9f6ea69..0a41506 100644
--- a/maec/test/encoding_test.py
+++ b/maec/test/encoding_test.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
"""Tests for various encoding issues throughout the library"""
diff --git a/maec/test/package/analysis_test.py b/maec/test/package/analysis_test.py
index 5b575e7..5583bfc 100644
--- a/maec/test/package/analysis_test.py
+++ b/maec/test/package/analysis_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
@@ -33,9 +33,9 @@ def test_round_trip(self):
o.source.organization = "ThreatExpert"
o.source.method = "triage"
o.source.url = "http://www.threatexpert.com"
-
+
o.start_datetime = "2014-08-06T18:30:00"
-
+
o2 = round_trip(o, True)
self.assertEqual(o.to_dict(), o2.to_dict())
diff --git a/maec/test/package/malware_subject_test.py b/maec/test/package/malware_subject_test.py
index 834b236..4b21890 100644
--- a/maec/test/package/malware_subject_test.py
+++ b/maec/test/package/malware_subject_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
@@ -69,4 +69,3 @@ def test_round_trip(self):
if __name__ == "__main__":
unittest.main()
-
\ No newline at end of file
diff --git a/maec/test/package/package_test.py b/maec/test/package/package_test.py
index 7c14707..e2f0034 100644
--- a/maec/test/package/package_test.py
+++ b/maec/test/package/package_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
@@ -69,4 +69,3 @@ def test_round_trip(self):
if __name__ == "__main__":
unittest.main()
-
diff --git a/maec/test/utils/nsparser_test.py b/maec/test/utils/nsparser_test.py
index b48911d..6215e12 100644
--- a/maec/test/utils/nsparser_test.py
+++ b/maec/test/utils/nsparser_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import unittest
diff --git a/maec/test/utils/parser_test.py b/maec/test/utils/parser_test.py
index 42812a7..c69cb0c 100644
--- a/maec/test/utils/parser_test.py
+++ b/maec/test/utils/parser_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
from mixbox.vendor.six import StringIO
diff --git a/maec/utils/__init__.py b/maec/utils/__init__.py
index 0fa8e93..ef331dc 100644
--- a/maec/utils/__init__.py
+++ b/maec/utils/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
"""MAEC utility methods"""
@@ -24,4 +24,4 @@ def flip_dict(d):
from .deduplicator import BundleDeduplicator # noqa
#Ensure MAEC namespaces get registered
-from .nsparser import * # noqa
+from .nsparser import * # noqa
diff --git a/maec/utils/comparator.py b/maec/utils/comparator.py
index 50e43fd..8aea9aa 100644
--- a/maec/utils/comparator.py
+++ b/maec/utils/comparator.py
@@ -1,5 +1,5 @@
# MAEC Comparator Classes
-import collections
+from mixbox import compat
class ComparisonResult(object):
def __init__(self, bundle_list, lookup_table):
@@ -154,7 +154,7 @@ def get_val(cls, obj, typed_field, hash_val, nested_elements = None):
val = getattr(obj.properties, str(typed_field))
if val is not None:
hash_val += str(typed_field) + ":"
- if isinstance(val, collections.MutableSequence):
+ if isinstance(val, compat.MutableSequence):
for list_item in val:
if '/' in str(nested_elements[0]):
hash_val += '['
diff --git a/maec/utils/deduplicator.py b/maec/utils/deduplicator.py
index 846acdf..7b96fa3 100644
--- a/maec/utils/deduplicator.py
+++ b/maec/utils/deduplicator.py
@@ -1,12 +1,12 @@
# MAEC Bundle Deduplicator Module
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
# See LICENSE.txt for complete terms
-import collections
import copy
+from mixbox import compat
from mixbox import entities
from cybox.core import RelatedObject, AssociatedObject
@@ -179,7 +179,7 @@ def get_typedfield_values(cls, val, name, values, ignoreCase=False):
# If the value is a mutable sequence, attempt to find TypedFields as
# in each item. EntityLists are Entity subclasses that can have
# TypedFields, so we don't make this an elif.
- if isinstance(val, collections.MutableSequence):
+ if isinstance(val, compat.MutableSequence):
for list_item in val:
cls.get_typedfield_values(list_item, name, values, ignoreCase)
diff --git a/maec/utils/merge.py b/maec/utils/merge.py
index 137cad4..b7258cc 100644
--- a/maec/utils/merge.py
+++ b/maec/utils/merge.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
"""Methods for merging MAEC documents"""
@@ -25,7 +25,7 @@ def dict_merge(target, *args):
for obj in args:
dict_merge(target, obj)
return target
-
+
# Recursively merge dicts and set non-dict values
obj = args[0]
if not isinstance(obj, dict):
@@ -104,7 +104,7 @@ def bin_malware_subjects(malware_subject_list, default_hash_type='md5'):
hash_type = str(hash.type_).lower()
# Get the hash value
hash_value = str(hash.simple_hash_value).lower()
-
+
# Check the hash type and bin accordingly
if hash_type == default_hash_type:
if hash_value in binned_subjects:
@@ -210,7 +210,7 @@ def update_relationships(malware_subject_list, id_mappings):
'''Update any existing Malware Subject relationships to account for merged Malware Subjects'''
for malware_subject in malware_subject_list:
if malware_subject.relationships:
- relationships = malware_subject.relationships
+ relationships = malware_subject.relationships
for relationship in relationships:
malware_subject_references = relationship.malware_subject_references
for malware_subject_reference in malware_subject_references:
diff --git a/maec/utils/nsparser.py b/maec/utils/nsparser.py
index 24a0ae0..a1c0647 100644
--- a/maec/utils/nsparser.py
+++ b/maec/utils/nsparser.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation
+# Copyright (c) 2018, The MITRE Corporation
# All rights reserved
# Compatible with MAEC v4.1
diff --git a/maec/utils/parser.py b/maec/utils/parser.py
index b330980..efedc3d 100644
--- a/maec/utils/parser.py
+++ b/maec/utils/parser.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import mixbox.parser
diff --git a/maec/version.py b/maec/version.py
index 3e11480..b87b594 100644
--- a/maec/version.py
+++ b/maec/version.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
-__version__ = "4.1.0.13"
+__version__ = "4.1.0.17"
diff --git a/maec/vocabs/vocabs.py b/maec/vocabs/vocabs.py
index 44eeed2..b06e7dd 100644
--- a/maec/vocabs/vocabs.py
+++ b/maec/vocabs/vocabs.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
from cybox.common.vocabs import VocabString, register_vocab
diff --git a/scripts/calculate_distance.py b/scripts/calculate_distance.py
index fa8f279..0677f56 100644
--- a/scripts/calculate_distance.py
+++ b/scripts/calculate_distance.py
@@ -3,7 +3,7 @@
# NOTE: This code imports and uses the maec.analytics.distance module, which uses the external numpy library.
# Numpy can be found here: https://pypi.python.org/pypi/numpy
-# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
+# Copyright (c) 2018, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
import os
@@ -26,7 +26,7 @@ def main():
# Parse the input files
if args.l:
- for file in args.l:
+ for file in args.l:
api_obj = maec.parse_xml_instance(file)['api']
if isinstance(api_obj, Package):
package_list.append(api_obj)
@@ -51,7 +51,7 @@ def main():
out_file = open(args.output, mode='w')
dist.print_distances(out_file)
out_file.close()
-
+
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..395669c
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,17 @@
+[bumpversion]
+current_version = 4.1.0.17
+parse = (?P\d+)\.(?P\d+)\.(?P\d+).(?P\d+)
+serialize = {major}.{minor}.{patch}.{revision}
+commit = True
+tag = True
+
+[bumpversion:file:maec/version.py]
+
+[bumpversion:file:docs/index.rst]
+
+[metadata]
+license_file = LICENSE.txt
+
+[bdist_wheel]
+universal = True
+
diff --git a/setup.py b/setup.py
index 56491a7..da68f08 100644
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,9 @@
#!/usr/bin/env python
-# Copyright (c) 2015 - The MITRE Corporation
+# Copyright (c) 2018 - The MITRE Corporation
# For license information, see the LICENSE.txt file
+from io import open # Allow `encoding` kwarg on Python 2.7
from os.path import abspath, dirname, join
@@ -11,6 +12,7 @@
BASE_DIR = dirname(abspath(__file__))
VERSION_FILE = join(BASE_DIR, 'maec', 'version.py')
+
def get_version():
with open(VERSION_FILE) as f:
for line in f.readlines():
@@ -20,24 +22,26 @@ def get_version():
raise AttributeError("Package does not have a __version__")
-with open('README.rst') as f:
- readme = f.read()
+def get_long_description():
+ with open('README.rst', encoding='utf-8') as f:
+ return f.read()
install_requires = [
- 'lxml>=2.2.3',
- 'mixbox>=0.0.13',
- 'cybox>=2.1.0.13.dev1,<2.1.1.0',
+ 'lxml>=2.2.3 ; python_version == "2.7" or python_version >= "3.5"',
+ 'lxml>=2.2.3,<4.4.0 ; python_version > "2.7" and python_version < "3.5"',
+ 'mixbox>=1.0.4',
+ 'cybox>=2.1.0.13,<2.1.1.0',
]
extras_require = {
'docs': [
- 'Sphinx==1.3.1',
- 'sphinx_rtd_theme==0.1.8',
+ 'Sphinx',
+ 'sphinx_rtd_theme',
],
'test': [
- "nose==1.3.0",
- "tox==1.6.1"
+ 'nose',
+ 'tox',
],
}
@@ -47,16 +51,29 @@ def get_version():
author="MAEC Project",
author_email="maec@mitre.org",
description="An API for parsing and creating MAEC content.",
- long_description=readme,
- url="http://maec.mitre.org",
+ long_description=get_long_description(),
+ url="https://maecproject.github.io/",
packages=find_packages(),
install_requires=install_requires,
extras_require=extras_require,
+ license="BSD",
classifiers=[
- "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
- ]
+ ],
+ project_urls={
+ 'Documentation': 'https://maec.readthedocs.io/',
+ 'Source Code': 'https://github.com/MAECProject/python-maec/',
+ 'Bug Tracker': 'https://github.com/MAECProject/python-maec/issues/',
+ },
)
diff --git a/tox.ini b/tox.ini
index f1eb433..d50a0b4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,21 +1,28 @@
[tox]
-envlist = py26, py27, py33, py34, py35, rhel6
+envlist = py27, py34, py35, py36, py37, py38, docs, packaging
[testenv]
commands =
nosetests maec
- sphinx-build -b doctest docs docs/_build/doctest
- sphinx-build -b html docs docs/_build/html
deps =
-rrequirements.txt
-[testenv:rhel6]
-basepython=python2.6
+[testenv:docs]
commands =
- nosetests maec
+ sphinx-build -W -b doctest -d {envtmpdir}/doctrees docs {envtmpdir}/doctest
+ sphinx-build -W -b html -d {envtmpdir}/doctrees docs {envtmpdir}/html
+
+[testenv:packaging]
deps =
- cybox>=2.1.0.13.dev1
- lxml==2.2.3
- mixbox>=0.0.13
- python-dateutil==1.4.1
- nose
+ readme_renderer
+commands =
+ python setup.py check -r -s
+
+[travis]
+python =
+ 2.7: py27, docs, packaging
+ 3.4: py34
+ 3.5: py35
+ 3.6: py36, docs, packaging
+ 3.7: py37
+ 3.8: py38