1# Copyright (c) 2017, The MITRE Corporation. All rights reserved.
2# See LICENSE.txt for complete terms.
3
4import sys
5
6from mixbox.binding_utils import *
7from . import cybox_common
8import cybox.objects
9
10
11class ProductObjectType(cybox_common.ObjectPropertiesType):
12    """The ProductObjectType type is intended to characterize software or
13    hardware products."""
14
15    subclass = None
16    superclass = cybox_common.ObjectPropertiesType
17    def __init__(self, object_reference=None, Custom_Properties=None, xsi_type=None, Edition=None, Language=None, Product=None, Update=None, Vendor=None, Version=None, Device_Details=None):
18        super(ProductObjectType, self).__init__(object_reference, Custom_Properties, xsi_type )
19        self.Edition = Edition
20        self.Language = Language
21        self.Product = Product
22        self.Update = Update
23        self.Vendor = Vendor
24        self.Version = Version
25        self.Device_Details = Device_Details
26    def factory(*args_, **kwargs_):
27        if ProductObjectType.subclass:
28            return ProductObjectType.subclass(*args_, **kwargs_)
29        else:
30            return ProductObjectType(*args_, **kwargs_)
31    factory = staticmethod(factory)
32    def get_Edition(self): return self.Edition
33    def set_Edition(self, Edition): self.Edition = Edition
34    def validate_StringObjectPropertyType(self, value):
35        # Validate type cybox_common.StringObjectPropertyType, a restriction on None.
36        pass
37    def get_Language(self): return self.Language
38    def set_Language(self, Language): self.Language = Language
39    def get_Product(self): return self.Product
40    def set_Product(self, Product): self.Product = Product
41    def get_Update(self): return self.Update
42    def set_Update(self, Update): self.Update = Update
43    def get_Vendor(self): return self.Vendor
44    def set_Vendor(self, Vendor): self.Vendor = Vendor
45    def get_Version(self): return self.Version
46    def set_Version(self, Version): self.Version = Version
47    def get_Device_Details(self): return self.Device_Details
48    def set_Device_Details(self, Device_Details): self.Device_Details = Device_Details
49    def hasContent_(self):
50        if (
51            self.Edition is not None or
52            self.Language is not None or
53            self.Product is not None or
54            self.Update is not None or
55            self.Vendor is not None or
56            self.Version is not None or
57            self.Device_Details is not None or
58            super(ProductObjectType, self).hasContent_()
59            ):
60            return True
61        else:
62            return False
63    def export(self, lwrite, level, namespace_='ProductObj:', name_='ProductObjectType', namespacedef_='', pretty_print=True):
64        if pretty_print:
65            eol_ = '\n'
66        else:
67            eol_ = ''
68        showIndent(lwrite, level, pretty_print)
69        lwrite('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
70        already_processed = set()
71        self.exportAttributes(lwrite, level, already_processed, namespace_, name_='ProductObjectType')
72        if self.hasContent_():
73            lwrite('>%s' % (eol_, ))
74            self.exportChildren(lwrite, level + 1, namespace_, name_, pretty_print=pretty_print)
75            showIndent(lwrite, level, pretty_print)
76            lwrite('</%s%s>%s' % (namespace_, name_, eol_))
77        else:
78            lwrite('/>%s' % (eol_, ))
79    def exportAttributes(self, lwrite, level, already_processed, namespace_='ProductObj:', name_='ProductObjectType'):
80        super(ProductObjectType, self).exportAttributes(lwrite, level, already_processed, namespace_, name_='ProductObjectType')
81    def exportChildren(self, lwrite, level, namespace_='ProductObj:', name_='ProductObjectType', fromsubclass_=False, pretty_print=True):
82        super(ProductObjectType, self).exportChildren(lwrite, level, 'ProductObj:', name_, True, pretty_print=pretty_print)
83        if pretty_print:
84            eol_ = '\n'
85        else:
86            eol_ = ''
87        if self.Edition is not None:
88            self.Edition.export(lwrite, level, 'ProductObj:', name_='Edition', pretty_print=pretty_print)
89        if self.Language is not None:
90            self.Language.export(lwrite, level, 'ProductObj:', name_='Language', pretty_print=pretty_print)
91        if self.Product is not None:
92            self.Product.export(lwrite, level, 'ProductObj:', name_='Product', pretty_print=pretty_print)
93        if self.Update is not None:
94            self.Update.export(lwrite, level, 'ProductObj:', name_='Update', pretty_print=pretty_print)
95        if self.Vendor is not None:
96            self.Vendor.export(lwrite, level, 'ProductObj:', name_='Vendor', pretty_print=pretty_print)
97        if self.Version is not None:
98            self.Version.export(lwrite, level, 'ProductObj:', name_='Version', pretty_print=pretty_print)
99        if self.Device_Details is not None:
100            self.Device_Details.export(lwrite, level, 'ProductObj:', name_='Device_Details', pretty_print=pretty_print)
101    def build(self, node):
102        self.__sourcenode__ = node
103        already_processed = set()
104        self.buildAttributes(node, node.attrib, already_processed)
105        for child in node:
106            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
107            self.buildChildren(child, node, nodeName_)
108    def buildAttributes(self, node, attrs, already_processed):
109        super(ProductObjectType, self).buildAttributes(node, attrs, already_processed)
110    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
111        if nodeName_ == 'Edition':
112            obj_ = cybox_common.StringObjectPropertyType.factory()
113            obj_.build(child_)
114            self.set_Edition(obj_)
115        elif nodeName_ == 'Language':
116            obj_ = cybox_common.StringObjectPropertyType.factory()
117            obj_.build(child_)
118            self.set_Language(obj_)
119        elif nodeName_ == 'Product':
120            obj_ = cybox_common.StringObjectPropertyType.factory()
121            obj_.build(child_)
122            self.set_Product(obj_)
123        elif nodeName_ == 'Update':
124            obj_ = cybox_common.StringObjectPropertyType.factory()
125            obj_.build(child_)
126            self.set_Update(obj_)
127        elif nodeName_ == 'Vendor':
128            obj_ = cybox_common.StringObjectPropertyType.factory()
129            obj_.build(child_)
130            self.set_Vendor(obj_)
131        elif nodeName_ == 'Version':
132            obj_ = cybox_common.StringObjectPropertyType.factory()
133            obj_.build(child_)
134            self.set_Version(obj_)
135        elif nodeName_ == 'Device_Details':
136            type_name_ = child_.attrib.get(
137                '{http://www.w3.org/2001/XMLSchema-instance}type')
138            if type_name_ is None:
139                type_name_ = child_.attrib.get('type')
140            if type_name_ is not None:
141                type_names_ = type_name_.split(':')
142                if len(type_names_) == 1:
143                    type_name_ = type_names_[0]
144                else:
145                    type_name_ = type_names_[1]
146                class_ = cybox.objects.get_class_for_object_type(type_name_)._binding_class
147                obj_ = class_.factory()
148                obj_.build(child_)
149            else:
150                raise NotImplementedError(
151                    'Class not implemented for <Device_Details> element')
152            self.set_Device_Details(obj_)
153
154        super(ProductObjectType, self).buildChildren(child_, node, nodeName_, True)
155# end class ProductObjectType
156
157GDSClassesMapping = {
158    'Build_Utility': cybox_common.BuildUtilityType,
159    'Errors': cybox_common.ErrorsType,
160    'Time': cybox_common.TimeType,
161    'Certificate_Issuer': cybox_common.StringObjectPropertyType,
162    'Metadata': cybox_common.MetadataType,
163    'Hash': cybox_common.HashType,
164    'Update': cybox_common.StringObjectPropertyType,
165    'Information_Source_Type': cybox_common.ControlledVocabularyStringType,
166    'Block_Hash_Value': cybox_common.HashValueType,
167    'Fuzzy_Hash_Structure': cybox_common.FuzzyHashStructureType,
168    'SubDatum': cybox_common.MetadataType,
169    'Segment_Hash': cybox_common.HashValueType,
170    'Digital_Signature': cybox_common.DigitalSignatureInfoType,
171    'Code_Snippets': cybox_common.CodeSnippetsType,
172    'Value': cybox_common.StringObjectPropertyType,
173    'Length': cybox_common.IntegerObjectPropertyType,
174    'Encoding': cybox_common.ControlledVocabularyStringType,
175    'Internationalization_Settings': cybox_common.InternationalizationSettingsType,
176    'Tool_Configuration': cybox_common.ToolConfigurationType,
177    'Signature_Description': cybox_common.StringObjectPropertyType,
178    'English_Translation': cybox_common.StringObjectPropertyType,
179    'Functions': cybox_common.FunctionsType,
180    'String_Value': cybox_common.StringObjectPropertyType,
181    'Build_Utility_Platform_Specification': cybox_common.PlatformSpecificationType,
182    'Compiler_Informal_Description': cybox_common.CompilerInformalDescriptionType,
183    'System': cybox_common.ObjectPropertiesType,
184    'Platform': cybox_common.PlatformSpecificationType,
185    'Version': cybox_common.StringObjectPropertyType,
186    'Usage_Context_Assumptions': cybox_common.UsageContextAssumptionsType,
187    'Type': cybox_common.ControlledVocabularyStringType,
188    'Compilers': cybox_common.CompilersType,
189    'Vendor': cybox_common.StringObjectPropertyType,
190    'String': cybox_common.ExtractedStringType,
191    'Tool': cybox_common.ToolInformationType,
192    'Build_Information': cybox_common.BuildInformationType,
193    'Tool_Hashes': cybox_common.HashListType,
194    'Compiler_Platform_Specification': cybox_common.PlatformSpecificationType,
195    'Error_Instances': cybox_common.ErrorInstancesType,
196    'Data_Segment': cybox_common.StringObjectPropertyType,
197    'Certificate_Subject': cybox_common.StringObjectPropertyType,
198    'Language': cybox_common.StringObjectPropertyType,
199    'Property': cybox_common.PropertyType,
200    'Strings': cybox_common.ExtractedStringsType,
201    'File_System_Offset': cybox_common.IntegerObjectPropertyType,
202    'Reference_Description': cybox_common.StructuredTextType,
203    'User_Account_Info': cybox_common.ObjectPropertiesType,
204    'Configuration_Settings': cybox_common.ConfigurationSettingsType,
205    'Simple_Hash_Value': cybox_common.SimpleHashValueType,
206    'Byte_String_Value': cybox_common.HexBinaryObjectPropertyType,
207    'Instance': cybox_common.ObjectPropertiesType,
208    'Import': cybox_common.StringObjectPropertyType,
209    'Identifier': cybox_common.PlatformIdentifierType,
210    'Tool_Specific_Data': cybox_common.ToolSpecificDataType,
211    'Execution_Environment': cybox_common.ExecutionEnvironmentType,
212    'Dependencies': cybox_common.DependenciesType,
213    'Offset': cybox_common.IntegerObjectPropertyType,
214    'Date': cybox_common.DateRangeType,
215    'Hashes': cybox_common.HashListType,
216    'Segments': cybox_common.HashSegmentsType,
217    'Segment_Count': cybox_common.IntegerObjectPropertyType,
218    'Usage_Context_Assumption': cybox_common.StructuredTextType,
219    'Block_Hash': cybox_common.FuzzyHashBlockType,
220    'Dependency': cybox_common.DependencyType,
221    'Error': cybox_common.ErrorType,
222    'Trigger_Point': cybox_common.HexBinaryObjectPropertyType,
223    'Environment_Variable': cybox_common.EnvironmentVariableType,
224    'Byte_Run': cybox_common.ByteRunType,
225    'Contributors': cybox_common.PersonnelType,
226    'Image_Offset': cybox_common.IntegerObjectPropertyType,
227    'Imports': cybox_common.ImportsType,
228    'Library': cybox_common.LibraryType,
229    'Edition': cybox_common.StringObjectPropertyType,
230    'References': cybox_common.ToolReferencesType,
231    'Internal_Strings': cybox_common.InternalStringsType,
232    'Custom_Properties': cybox_common.CustomPropertiesType,
233    'Configuration_Setting': cybox_common.ConfigurationSettingType,
234    'Libraries': cybox_common.LibrariesType,
235    'Function': cybox_common.StringObjectPropertyType,
236    'Product': cybox_common.StringObjectPropertyType,
237    'Description': cybox_common.StructuredTextType,
238    'Code_Snippet': cybox_common.ObjectPropertiesType,
239    'Build_Configuration': cybox_common.BuildConfigurationType,
240    'Address': cybox_common.HexBinaryObjectPropertyType,
241    'Search_Within': cybox_common.IntegerObjectPropertyType,
242    'Segment': cybox_common.HashSegmentType,
243    'Compiler': cybox_common.CompilerType,
244    'Name': cybox_common.StringObjectPropertyType,
245    'Tool_Type': cybox_common.ControlledVocabularyStringType,
246    'Block_Size': cybox_common.IntegerObjectPropertyType,
247    'Search_Distance': cybox_common.IntegerObjectPropertyType,
248    'Fuzzy_Hash_Value': cybox_common.FuzzyHashValueType,
249    'Dependency_Description': cybox_common.StructuredTextType,
250    'Contributor': cybox_common.ContributorType,
251    'Tools': cybox_common.ToolsInformationType,
252    'Data_Size': cybox_common.DataSizeType,
253    'Device_Details': cybox_common.ObjectPropertiesType,
254}
255
256USAGE_TEXT = """
257Usage: python <Parser>.py [ -s ] <in_xml_file>
258"""
259
260def usage():
261    print(USAGE_TEXT)
262    sys.exit(1)
263
264def get_root_tag(node):
265    tag = Tag_pattern_.match(node.tag).groups()[-1]
266    rootClass = GDSClassesMapping.get(tag)
267    if rootClass is None:
268        rootClass = globals().get(tag)
269    return tag, rootClass
270
271def parse(inFileName):
272    doc = parsexml_(inFileName)
273    rootNode = doc.getroot()
274    rootTag, rootClass = get_root_tag(rootNode)
275    if rootClass is None:
276        rootTag = 'Product'
277        rootClass = ProductObjectType
278    rootObj = rootClass.factory()
279    rootObj.build(rootNode)
280    # Enable Python to collect the space used by the DOM.
281    doc = None
282#    sys.stdout.write('<?xml version="1.0" ?>\n')
283#    rootObj.export(sys.stdout.write, 0, name_=rootTag,
284#        namespacedef_='',
285#        pretty_print=True)
286    return rootObj
287
288def parseEtree(inFileName):
289    doc = parsexml_(inFileName)
290    rootNode = doc.getroot()
291    rootTag, rootClass = get_root_tag(rootNode)
292    if rootClass is None:
293        rootTag = 'Product'
294        rootClass = ProductObjectType
295    rootObj = rootClass.factory()
296    rootObj.build(rootNode)
297    # Enable Python to collect the space used by the DOM.
298    doc = None
299    rootElement = rootObj.to_etree(None, name_=rootTag)
300    content = etree_.tostring(rootElement, pretty_print=True,
301        xml_declaration=True, encoding="utf-8")
302    sys.stdout.write(content)
303    sys.stdout.write('\n')
304    return rootObj, rootElement
305
306def parseString(inString):
307    from mixbox.vendor.six import StringIO
308    doc = parsexml_(StringIO(inString))
309    rootNode = doc.getroot()
310    rootTag, rootClass = get_root_tag(rootNode)
311    if rootClass is None:
312        rootTag = 'Product'
313        rootClass = ProductObjectType
314    rootObj = rootClass.factory()
315    rootObj.build(rootNode)
316    # Enable Python to collect the space used by the DOM.
317    doc = None
318#    sys.stdout.write('<?xml version="1.0" ?>\n')
319#    rootObj.export(sys.stdout.write, 0, name_="Product",
320#        namespacedef_='')
321    return rootObj
322
323def main():
324    args = sys.argv[1:]
325    if len(args) == 1:
326        parse(args[0])
327    else:
328        usage()
329
330if __name__ == '__main__':
331    #import pdb; pdb.set_trace()
332    main()
333
334__all__ = [
335    "ProductObjectType"
336    ]
337