Hi Nicholas,

sorry for the long delay in getting back to you on this topic. I finally
set aside the time to go through your work, and it's quite
impressive. I'll need to do a bit more testing, but we should be able to
integrate your contribution into the security repository, and use that
to provide OVAL definitions again.

Thanks again for your work. Cheers,

--Seb

On Nov/13, Luedtke, Nicholas S wrote:
> Attached is a working solution to this bug. Right now parsing the JSON
> Security Tracker Information results in a one definition per CVE. I
> hope to reduce this to one definition per package. (Shouldn't be too
> much work) Also included in the tar is are more updates to the legacy
> versions of parsing the dsa/wml files. If you need a debian oval
> interpreter I previously attached one to this forum.
> 
> I encourage you to use -h option for the JSON parsing script as
> downloading the security tracker each time is cumbersome.
> 
> shasums:
> 5d13f72cccc6ad1774e2437c98c26bebfc2100ac  68910 diff.txt
> 57fa67e77ed5212d65deca0483b7ac90b5bb7203  21423 oval.tar.gz
> 
> -- 
> Nicholas Luedtke
> Linux for HPE Helion OpenStack, Hewlett Packard Enterprise


> Binary files oval_old/oval/definition/differ.pyc and 
> oval/oval/definition/differ.pyc differ
> diff -urN oval_old/oval/definition/generator.py 
> oval/oval/definition/generator.py
> --- oval_old/oval/definition/generator.py     2011-10-12 15:14:34.000000000 
> -0600
> +++ oval/oval/definition/generator.py 2015-11-13 11:20:30.043834000 -0700
> @@ -1,5 +1,5 @@
>  # -*- coding: utf-8 -*-
> -# oval.definitio.generator - generate well-formed xml file with 
> +# oval.definition.generator - generate well-formed xml file with
>  # OVAL definitions of Debian Security Advisories.
>  # Use various optimizations to minimize result XML
>  #
> @@ -19,44 +19,44 @@
>  RE_XML_ILLEGAL = u'([\u0000-\u0008\u000b-\u000c\u000e-\u001f\ufffe-\uffff])' 
> + u'|' + u'([%s-%s][^%s-%s])|([^%s-%s][%s-%s])|([%s-%s]$)|(^[%s-%s])' % 
> (unichr(0xd800),unichr(0xdbff),unichr(0xdc00),unichr(0xdfff), 
> unichr(0xd800),unichr(0xdbff),unichr(0xdc00),unichr(0xdfff), 
> unichr(0xd800),unichr(0xdbff),unichr(0xdc00),unichr(0xdfff)) 
>  regex = re.compile(RE_XML_ILLEGAL)
>  
> -                                     
> +
>  class OvalGeneratorException (Exception):
>      pass
>  
>  class DSAFormatException (OvalGeneratorException):
> -     code = 1
> -     
> +    code = 1
> +
>  def __createXMLElement (name, descr = None, attrs = {}):
> -     """
> -             Create XML element with text descr and attributes attrs
> -             
> -             Keyword arguments:
> -             name -- Name of XML element
> -             descr -- content of textNode (default None)
> -             attrs -- attributes of element (default {})
> -
> -             Return created XML element
> -     """
> -
> -     doc = xml.dom.minidom.Document ()
> -     element = doc.createElement (name)
> -     
> -     for (attr, value) in attrs.items():
> -                for match in regex.finditer(attr):
> -                    attr = attr[:match.start()] + "?" + attr[match.end():]
> -                for match in regex.finditer(value):
> -                    value = value[:match.start()] + "?" + value[match.end():]
> -             attribute = doc.createAttribute (attr.encode("utf8"))
> -             attribute.value = value.encode("utf8")
> -             element.attributes.setNamedItem (attribute)
> -     
> -     if descr != None:
> -                for match in regex.finditer(descr):
> -                    descr = descr[:match.start()] + "?" + descr[match.end():]
> -             description = doc.createTextNode (descr.encode("utf8"))
> -             element.appendChild (description)
> -     
> -     return (element)
> +    """
> +        Create XML element with text descr and attributes attrs
> +
> +        Keyword arguments:
> +        name -- Name of XML element
> +        descr -- content of textNode (default None)
> +        attrs -- attributes of element (default {})
> +
> +        Return created XML element
> +    """
> +
> +    doc = xml.dom.minidom.Document ()
> +    element = doc.createElement (name)
> +
> +    for (attr, value) in attrs.items():
> +        for match in regex.finditer(attr):
> +            attr = attr[:match.start()] + "?" + attr[match.end():]
> +        for match in regex.finditer(value):
> +            value = value[:match.start()] + "?" + value[match.end():]
> +        attribute = doc.createAttribute (attr.encode("utf8"))
> +        attribute.value = value.encode("utf8")
> +        element.attributes.setNamedItem (attribute)
> +
> +    if descr != None:
> +        for match in regex.finditer(descr):
> +            descr = descr[:match.start()] + "?" + descr[match.end():]
> +        description = doc.createTextNode (descr.encode("utf8"))
> +        element.appendChild (description)
> +
> +    return (element)
>  
>  namespace = "oval:org.debian.oval"
>  tests = __createXMLElement ("tests")
> @@ -66,464 +66,464 @@
>  testsCurId = 1
>  objectsCurId = 1
>  statesCurId = 1
> -
>  releaseArchHash = {"2.0" : 2, "2.1" : 4, "2.2":  6, "3.0" : 11, "3.1" : 12, 
> "4.0" : 11, "5.0": 12, "6.0": 11}
>  testsHash = {"arch" : {}, "release": {}, "obj": {}, "fileSte": {}, 
> "unameSte" : {}, "dpkgSte": {}} 
>  #We need more info about alpha, arm, hppa, bmips, lmips
>  unameArchTable = {'i386' : 'i686', 'amd64' : 'x86-64', 'ia64' : 'ia64', 
> 'powerpc' : 'ppc', 's390' : 's390x', 'm86k' : 'm86k'} 
>  
>  def __trimzero (val):
> -     value = val[:]
> -     while value[0] == "0":
> -             value = value[1:]
> -     return value
> +    value = val[:]
> +    while value[0] == "0":
> +        value = value[1:]
> +    return value
>  
>  def __getNewId (type):
> -     """Generate new unique id for tests, objects or states
> -     
> -             Argument keqywords:
> -             type -- type of generated id test | object | state
> -             
> -             return Generate id like <namespace>:tst|obj|ste:<id>
> -     """
> -     global testsCurId, objectsCurId, statesCurId
> -       
> -     if type == "test":
> -             result = "%s:tst:%d" % (namespace, testsCurId)
> -             testsCurId += 1
> -             
> -     if type == "object":
> -             result = "%s:obj:%d" % (namespace, objectsCurId)
> -             objectsCurId += 1
> -             
> -     if type == "state":
> -             result = "%s:ste:%d" % (namespace, statesCurId)
> -             statesCurId += 1
> -     
> -     return (result)
> +    """Generate new unique id for tests, objects or states
> +
> +        Argument keqywords:
> +        type -- type of generated id test | object | state
> +
> +        return Generate id like <namespace>:tst|obj|ste:<id>
> +    """
> +    global testsCurId, objectsCurId, statesCurId
> +
> +    if type == "test":
> +        result = "%s:tst:%d" % (namespace, testsCurId)
> +        testsCurId += 1
> +
> +    if type == "object":
> +        result = "%s:obj:%d" % (namespace, objectsCurId)
> +        objectsCurId += 1
> +
> +    if type == "state":
> +        result = "%s:ste:%d" % (namespace, statesCurId)
> +        statesCurId += 1
> +
> +    return result
>  
>  def __createOVALDpkginfoObject (name):
> -     """ Generate OVAL dpkginfo_object definition """
> -     
> -     if not testsHash["obj"].has_key(name):
> -             objectId = __getNewId ("object");
> -             object = __createXMLElement("dpkginfo_object",
> -                     attrs={"id":objectId, 
> -                             "version":"1",
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"})
> -             object.appendChild ( __createXMLElement ("name", name))
> -             objects.appendChild (object)
> -
> -             testsHash["obj"][name] = objectId
> -     
> -     return (testsHash["obj"][name])
> +    """ Generate OVAL dpkginfo_object definition """
> +
> +    if not testsHash["obj"].has_key(name):
> +        objectId = __getNewId ("object");
> +        object = __createXMLElement("dpkginfo_object",
> +            attrs={"id":objectId,
> +                "version":"1",
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"})
> +        object.appendChild ( __createXMLElement ("name", name))
> +        objects.appendChild (object)
> +
> +        testsHash["obj"][name] = objectId
> +
> +    return (testsHash["obj"][name])
>  
>  def __createOVALTextfilecontentObject (pattern, path = "/etc", filename = 
> "debian_version"):
> -     """ Generate OVAL textfilecontent_object definition """
> -     name = path + filename + pattern
> -     
> -     if not testsHash["obj"].has_key(name):
> -             objectId = __getNewId ("object");
> -             object = __createXMLElement("textfilecontent_object",
> -                     attrs={"id":objectId, 
> -                             "version":"1",
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#independent"})
> -             object.appendChild ( __createXMLElement ("path", path))
> -             object.appendChild ( __createXMLElement ("filename", filename))
> -             object.appendChild ( __createXMLElement ("line", pattern, 
> attrs={"operation" : "pattern match"}))
> -             objects.appendChild (object)
> -
> -             testsHash["obj"][name] = objectId
> -     
> -     return (testsHash["obj"][name])
> +    """ Generate OVAL textfilecontent_object definition """
> +    name = path + filename + pattern
> +
> +    if not testsHash["obj"].has_key(name):
> +        objectId = __getNewId ("object");
> +        object = __createXMLElement("textfilecontent_object",
> +            attrs={"id":objectId,
> +                "version":"1",
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#independent"})
> +        object.appendChild ( __createXMLElement ("path", path))
> +        object.appendChild ( __createXMLElement ("filename", filename))
> +        object.appendChild ( __createXMLElement ("line", pattern, 
> attrs={"operation" : "pattern match"}))
> +        objects.appendChild (object)
> +
> +        testsHash["obj"][name] = objectId
> +
> +    return (testsHash["obj"][name])
>  
>  def __createOVALUnameObject ():
> -     """ Generate OVAL textfilecontent_object definition """
> -     name = "uname_object"
> -     
> -     if not testsHash["obj"].has_key(name):
> -             objectId = __getNewId ("object");
> -             object = __createXMLElement("uname_object",
> -                     attrs={"id":objectId, 
> -                             "version":"1",
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"})
> -             objects.appendChild (object)
> -
> -             testsHash["obj"][name] = objectId
> -     
> -     return (testsHash["obj"][name])
> +    """ Generate OVAL textfilecontent_object definition """
> +    name = "uname_object"
> +
> +    if not testsHash["obj"].has_key(name):
> +        objectId = __getNewId ("object");
> +        object = __createXMLElement("uname_object",
> +            attrs={"id":objectId,
> +                "version":"1",
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"})
> +        objects.appendChild (object)
> +
> +        testsHash["obj"][name] = objectId
> +
> +    return (testsHash["obj"][name])
>  
>  def __createOVALState (value, operation = "less than"):
> -     """ Generate OVAL state definition 
> -     
> -             Use state hash for optimization of resulted XML
> -     """
> -     #TODO: Add arch state generation
> -     if not testsHash["dpkgSte"].has_key(operation) or not 
> testsHash["dpkgSte"][operation].has_key(value):
> -             stateId = __getNewId ("state")
> -
> -             state = __createXMLElement("dpkginfo_state", 
> -                     attrs={"id":stateId, 
> -                             "version":"1",
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"})
> -             state.appendChild ( __createXMLElement ("evr", "0:"+value, 
> -                                                                     
> {"datatype":"evr_string", 
> -                                                                        
> "operation":operation}))
> -             states.appendChild (state)
> -     
> -             testsHash["dpkgSte"][operation] = {value : stateId}
> -             
> -     return (testsHash["dpkgSte"][operation][value])
> +    """ Generate OVAL state definition
> +
> +        Use state hash for optimization of resulted XML
> +    """
> +    #TODO: Add arch state generation
> +    if not testsHash["dpkgSte"].has_key(operation) or not 
> testsHash["dpkgSte"][operation].has_key(value):
> +        stateId = __getNewId ("state")
> +
> +        state = __createXMLElement("dpkginfo_state",
> +            attrs={"id":stateId,
> +                "version":"1",
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"})
> +        state.appendChild ( __createXMLElement ("evr", "0:"+value,
> +                                    {"datatype":"evr_string",
> +                                       "operation":operation}))
> +        states.appendChild (state)
> +
> +        testsHash["dpkgSte"][operation] = {value : stateId}
> +
> +    return (testsHash["dpkgSte"][operation][value])
>  
>  def __createOVALUnameState (field, value, operation = "equals"):
> -     """ Generate OVAL uname state definition 
> -     
> -             Use unameArchTable to convert dsa arch to uname arch value
> -     """
> -     
> -     try:
> -             value = unameArchTable[value]
> -     except KeyError:
> -             pass
> -
> -     #TODO: Add arch state generation
> -     if not testsHash["unameSte"].has_key(operation) or not 
> testsHash["unameSte"][operation].has_key(value):
> -             stateId = __getNewId ("state")
> -
> -             state = __createXMLElement("uname_state", 
> -                     attrs={"id":stateId, 
> -                             "version":"1",
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"})
> -             state.appendChild ( __createXMLElement (field, value, 
> -                                                                     
> {"operation":operation}))
> -             states.appendChild (state)
> -     
> -             testsHash["unameSte"][operation] = {value : stateId}
> -             
> -     return (testsHash["unameSte"][operation][value])
> +    """ Generate OVAL uname state definition
> +
> +        Use unameArchTable to convert dsa arch to uname arch value
> +    """
> +
> +    try:
> +        value = unameArchTable[value]
> +    except KeyError:
> +        pass
> +
> +    #TODO: Add arch state generation
> +    if not testsHash["unameSte"].has_key(operation) or not 
> testsHash["unameSte"][operation].has_key(value):
> +        stateId = __getNewId ("state")
> +
> +        state = __createXMLElement("uname_state",
> +            attrs={"id":stateId,
> +                "version":"1",
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"})
> +        state.appendChild ( __createXMLElement (field, value,
> +                                    {"operation":operation}))
> +        states.appendChild (state)
> +
> +        testsHash["unameSte"][operation] = {value : stateId}
> +
> +    return (testsHash["unameSte"][operation][value])
>  
>  def __createOVALTextfilecontentState (value, operation = "equals"):
> -     """ Generate OVAL state definition 
> -     
> -             Use state hash for optimization of resulted XML
> -     """
> -     #TODO: Add arch state generation
> -     if not testsHash["fileSte"].has_key(operation) or not 
> testsHash["fileSte"][operation].has_key(value):
> -             stateId = __getNewId ("state")
> -
> -             state = __createXMLElement("textfilecontent_state", 
> -                     attrs={"id":stateId, 
> -                             "version":"1",
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#independent"})
> -             state.appendChild ( __createXMLElement ("line", value, 
> -                                                                     
> {"operation":operation}))
> -             states.appendChild (state)
> -     
> -             testsHash["fileSte"][operation] = {value : stateId}
> -             
> -     return (testsHash["fileSte"][operation][value])
> -     
> +    """ Generate OVAL state definition
> +
> +        Use state hash for optimization of resulted XML
> +    """
> +    #TODO: Add arch state generation
> +    if not testsHash["fileSte"].has_key(operation) or not 
> testsHash["fileSte"][operation].has_key(value):
> +        stateId = __getNewId ("state")
> +
> +        state = __createXMLElement("textfilecontent_state",
> +            attrs={"id":stateId,
> +                "version":"1",
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#independent"})
> +        state.appendChild ( __createXMLElement ("line", value,
> +                                    {"operation":operation}))
> +        states.appendChild (state)
> +
> +        testsHash["fileSte"][operation] = {value : stateId}
> +
> +    return (testsHash["fileSte"][operation][value])
> +
>  def __createDPKGTest(name, version):
> -     """ Generate OVAL DPKG test """
> -     
> -     ref = __getNewId ("test")
> -     test = __createXMLElement("dpkginfo_test", 
> -                     attrs={"id":ref, 
> -                             "version":"1", 
> -                             "check":"all",
> -                             "check_existence":"at_least_one_exists",
> -                             "comment":"%s is earlier than %s" % (name, 
> version),
> -                             
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#linux";
> -                     })
> -     test.appendChild ( __createXMLElement("object", attrs={"object_ref" : 
> __createOVALDpkginfoObject (name)}))
> -     test.appendChild ( __createXMLElement("state", attrs={"state_ref" : 
> __createOVALState (version)}))
> -     tests.appendChild(test)
> +    """ Generate OVAL DPKG test """
> +
> +    ref = __getNewId ("test")
> +    test = __createXMLElement("dpkginfo_test",
> +            attrs={"id":ref,
> +                "version":"1",
> +                "check":"all",
> +                "check_existence":"at_least_one_exists",
> +                "comment":"%s is earlier than %s" % (name, version),
> +                
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#linux";
> +            })
> +    test.appendChild ( __createXMLElement("object", attrs={"object_ref" : 
> __createOVALDpkginfoObject (name)}))
> +    test.appendChild ( __createXMLElement("state", attrs={"state_ref" : 
> __createOVALState (version)}))
> +    tests.appendChild(test)
> +
> +    return (ref)
>  
> -     return (ref)
> -     
>  def __createTest(testType, value):
> -     """ Generate OVAL test for release or architecture cases"""
> -     
> -     if not testsHash[testType].has_key(value):
> -             comment = None
> -                     
> -             ref = __getNewId("test")
> -             
> -             if testType == "release":
> -                     objectId = __createOVALTextfilecontentObject ("\d\.\d")
> -                     comment = "Debian GNU/Linux %s is installed" % value
> -                     
> -                     test = __createXMLElement("textfilecontent_test", 
> -                             attrs={"id":ref, 
> -                                     "version":"1", 
> -                                     "check":"all",
> -                                     "check_existence":"at_least_one_exists",
> -                                     "comment":comment,
> -                                     
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#independent";
> -                     })
> -                     test.appendChild ( __createXMLElement("object", 
> attrs={"object_ref" : objectId}))
> -                     test.appendChild ( __createXMLElement("state", 
> attrs={"state_ref" : __createOVALTextfilecontentState (value, "equals")}))
> -                     
> -             else:
> -                     objectId = __createOVALUnameObject ()
> -                     comment = "Installed architecture is %s" % value
> -                     
> -                     test = __createXMLElement("uname_test", 
> -                             attrs={"id":ref, 
> -                                     "version":"1", 
> -                                     "check":"all",
> -                                     "check_existence":"at_least_one_exists",
> -                                     "comment":comment,
> -                                     
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#unix";
> -                     })
> -                     test.appendChild ( __createXMLElement("object", 
> attrs={"object_ref" : objectId}))
> -                     if value != "all":
> -                             test.appendChild ( __createXMLElement("state", 
> attrs={"state_ref" : __createOVALUnameState ("processor_type", value, 
> "equals")}))
> -             
> -             tests.appendChild(test)
> -                             
> -             testsHash[testType][value] = ref
> -     
> -     return (testsHash[testType][value])
> +    """ Generate OVAL test for release or architecture cases"""
> +
> +    if not testsHash[testType].has_key(value):
> +        comment = None
> +
> +        ref = __getNewId("test")
> +
> +        if testType == "release":
> +            objectId = __createOVALTextfilecontentObject ("\d\.\d")
> +            comment = "Debian GNU/Linux %s is installed" % value
> +
> +            test = __createXMLElement("textfilecontent_test",
> +                attrs={"id":ref,
> +                    "version":"1",
> +                    "check":"all",
> +                    "check_existence":"at_least_one_exists",
> +                    "comment":comment,
> +                    
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#independent";
> +            })
> +            test.appendChild ( __createXMLElement("object", 
> attrs={"object_ref" : objectId}))
> +            test.appendChild ( __createXMLElement("state", 
> attrs={"state_ref" : __createOVALTextfilecontentState (value, "equals")}))
> +
> +        else:
> +            objectId = __createOVALUnameObject ()
> +            comment = "Installed architecture is %s" % value
> +
> +            test = __createXMLElement("uname_test",
> +                attrs={"id":ref,
> +                    "version":"1",
> +                    "check":"all",
> +                    "check_existence":"at_least_one_exists",
> +                    "comment":comment,
> +                    
> "xmlns":"http://oval.mitre.org/XMLSchema/oval-definitions-5#unix";
> +            })
> +            test.appendChild ( __createXMLElement("object", 
> attrs={"object_ref" : objectId}))
> +            if value != "all":
> +                test.appendChild ( __createXMLElement("state", 
> attrs={"state_ref" : __createOVALUnameState ("processor_type", value, 
> "equals")}))
> +
> +        tests.appendChild(test)
> +
> +        testsHash[testType][value] = ref
> +
> +    return (testsHash[testType][value])
>  
>  def __createGeneratorHeader ():
> -     """
> -             Create OVAL definitions XML generator element.
> -             
> -             return  xml.dom.minidom.Document with header information
> -     """
> -     
> -     doc = xml.dom.minidom.Document ()
> -     generator = doc.createElement ("generator")
> -
> -     generator.appendChild ( __createXMLElement ("oval:product_name", 
> "Debian") )
> -     generator.appendChild ( __createXMLElement ("oval:schema_version", 
> "5.3") )
> -     generator.appendChild ( __createXMLElement ("oval:timestamp", 
> datetime.datetime.now().strftime ("%Y-%m-%dT%H:%M:%S.188-04:00")) )
> +    """
> +        Create OVAL definitions XML generator element.
> +
> +        return  xml.dom.minidom.Document with header information
> +    """
> +
> +    doc = xml.dom.minidom.Document ()
> +    generator = doc.createElement ("generator")
> +
> +    generator.appendChild ( __createXMLElement ("oval:product_name", 
> "Debian") )
> +    generator.appendChild ( __createXMLElement ("oval:schema_version", 
> "5.3") )
> +    generator.appendChild ( __createXMLElement ("oval:timestamp", 
> datetime.datetime.now().strftime ("%Y-%m-%dT%H:%M:%S.188-04:00")) )
>  
> -     return (generator)
> +    return (generator)
>  
>  def createPlatformDefinition (release, data, dsa):
> -     """ Generate OVAL definitions for current release
> -     
> -             Generate full criteria tree for specified release. Tests, 
> states and objects 
> -             stored in global dictionaries.
> -             Use differ module for otimize generated tree.
> -             
> -             Argument keywords:
> -             release -- Debian release
> -             data -- dict with information about packages
> -             dsa - DSA id
> -             
> -             return Generated XML fragment
> -     """
> -     #Raise exception if we receive too small data
> -     if len(data) == 0:
> -             logging.log(logging.WARNING, "DSA %s: Information of affected 
> platforms is not available." % dsa)
> -     
> -     softwareCriteria = __createXMLElement ("criteria", attrs = {"comment" : 
> "Release section", "operator" : "AND"})
> -     softwareCriteria.appendChild ( __createXMLElement ("criterion", 
> attrs={"test_ref" : __createTest("release", release), "comment" : "Debian %s 
> is installed" % release}))
> -             
> -     archCriteria = __createXMLElement ("criteria", attrs = {"comment" : 
> "Architecture section", "operator" : "OR"})
> -
> -     # Handle architecture independed section
> -     if data.has_key ("all"):
> -             archIndepCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Architecture independet section", "operator" : "AND"})
> -             
> -             archIndepCriteria.appendChild ( __createXMLElement 
> ("criterion", attrs = {"test_ref" : __createTest("arch", "all"), "comment" : 
> "all architecture"}))
> -             #Build packages section only if we have more then one package
> -             if len (data["all"]) > 1:
> -                     packageCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Packages section", "operator" : "OR"})
> -                     archIndepCriteria.appendChild (packageCriteria)
> -             else:
> -                     packageCriteria = archIndepCriteria
> -                     
> -             for pkg in data["all"].keys():
> -                     packageCriteria.appendChild ( __createXMLElement 
> ("criterion", attrs = {"test_ref" : __createDPKGTest(pkg, data["all"][pkg]), 
> "comment" : "%s DPKG is earlier than %s" % (pkg, data["all"][pkg])}))
> -     
> -             archCriteria.appendChild (archIndepCriteria)
> -
> -     # Optimize packages tree in 2 stages
> -     diff = differ ()
> -     for i in range(2):
> -             
> -             if i == 0:
> -                     dsaData = data
> -             else:
> -                     dsaData = diff.getDiffer()
> -             
> -             diff.Clean()    
> -             for (key, value) in dsaData.iteritems():
> -                     if key != "all":
> -                             diff.compareElement(key, value)
> -             
> -             eq = diff.getEqual()
> -             di = diff.getDiffer()
> -             
> -             # Generate XML for optimized packages
> -             if (len(eq)):
> -                     if len(diff.getArchs()) != releaseArchHash[release]:
> -                             archDependCriteria = __createXMLElement 
> ("criteria", attrs={"comment" : "Architecture depended section", "operator" : 
> "AND"})   
> -                             
> -                             supportedArchCriteria = __createXMLElement 
> ("criteria", attrs={"comment" : "Supported architectures section", "operator" 
> : "OR"})
> -                             for arch in diff.getArchs():
> -                                     supportedArchCriteria.appendChild ( 
> __createXMLElement ("criterion", attrs = {"test_ref" : __createTest("arch", 
> arch), "comment" : "%s architecture" % arch}))
> -                                     archDependCriteria.appendChild 
> (supportedArchCriteria)
> -             
> -                     packageCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Packages section", "operator" : "OR"})
> -                     for bpkg in eq.keys():
> -                             packageCriteria.appendChild ( 
> __createXMLElement ("criterion", attrs = {"test_ref" : __createDPKGTest(bpkg, 
> eq[bpkg]), "comment" : "%s DPKG is earlier than %s" % (bpkg, eq[bpkg])}))
> -                     
> -                     if len(diff.getArchs()) != releaseArchHash[release]:    
>                 
> -                             archDependCriteria.appendChild (packageCriteria)
> -                             archCriteria.appendChild (archDependCriteria)
> -                     else:
> -                             archCriteria.appendChild (packageCriteria)
> -             
> -     # Generate XML for all other packages
> -     if len(di):
> -             archDependCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Architecture depended section", "operator" : "AND"})
> -                     
> -             for (key, value) in di.iteritems():
> -                     supportedPlatformCriteria = __createXMLElement 
> ("criteria", attrs={"comment" : "Supported platform section", "operator" : 
> "AND"})
> -                     supportedPlatformCriteria.appendChild ( 
> __createXMLElement ("criterion", attrs = {"test_ref" : __createTest("arch", 
> key), "comment" : "%s architecture" % key}))
> -             
> -                     packageCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Packages section", "operator" : "OR"})
> -                                     
> -                     for bpkg in di[key].keys():
> -                             packageCriteria.appendChild ( 
> __createXMLElement ("criterion", attrs = {"test_ref" : __createDPKGTest(bpkg, 
> di[key][bpkg]), "comment" : "%s DPKG is earlier than %s" % (bpkg, 
> di[key][bpkg])}))
> -                             supportedPlatformCriteria.appendChild 
> (packageCriteria)
> -             
> -             archDependCriteria.appendChild (supportedPlatformCriteria)
> -             archCriteria.appendChild (archDependCriteria)   
> -                     
> -     softwareCriteria.appendChild (archCriteria)     
> -     
> -     return (softwareCriteria)
> +    """ Generate OVAL definitions for current release
> +
> +        Generate full criteria tree for specified release. Tests, states and 
> objects
> +        stored in global dictionaries.
> +        Use differ module for optimize generated tree.
> +
> +        Argument keywords:
> +        release -- Debian release
> +        data -- dict with information about packages
> +        dsa - DSA id
> +
> +        return Generated XML fragment
> +    """
> +    #Raise exception if we receive too small data
> +    if len(data) == 0:
> +        logging.log(logging.WARNING, "DSA %s: Information of affected 
> platforms is not available." % dsa)
> +
> +    softwareCriteria = __createXMLElement ("criteria", attrs = {"comment" : 
> "Release section", "operator" : "AND"})
> +    softwareCriteria.appendChild ( __createXMLElement ("criterion", 
> attrs={"test_ref" : __createTest("release", release), "comment" : "Debian %s 
> is installed" % release}))
> +
> +    archCriteria = __createXMLElement ("criteria", attrs = {"comment" : 
> "Architecture section", "operator" : "OR"})
> +
> +    # Handle architecture independent section
> +    if data.has_key ("all"):
> +        archIndepCriteria = __createXMLElement ("criteria", attrs={"comment" 
> : "Architecture independent section", "operator" : "AND"})
> +
> +        archIndepCriteria.appendChild ( __createXMLElement ("criterion", 
> attrs = {"test_ref" : __createTest("arch", "all"), "comment" : "all 
> architecture"}))
> +        #Build packages section only if we have more then one package
> +        if len (data["all"]) > 1:
> +            packageCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Packages section", "operator" : "OR"})
> +            archIndepCriteria.appendChild (packageCriteria)
> +        else:
> +            packageCriteria = archIndepCriteria
> +
> +        for pkg in data["all"].keys():
> +            packageCriteria.appendChild ( __createXMLElement ("criterion", 
> attrs = {"test_ref" : __createDPKGTest(pkg, data["all"][pkg]), "comment" : 
> "%s DPKG is earlier than %s" % (pkg, data["all"][pkg])}))
> +
> +        archCriteria.appendChild (archIndepCriteria)
> +
> +    # Optimize packages tree in 2 stages
> +    diff = differ()
> +    for i in range(2):
> +
> +        if i == 0:
> +            dsaData = data
> +        else:
> +            dsaData = diff.getDiffer()
> +
> +        diff.Clean()
> +        for (key, value) in dsaData.iteritems():
> +            if key != "all":
> +                diff.compareElement(key, value)
> +
> +        eq = diff.getEqual()
> +        di = diff.getDiffer()
> +
> +        # Generate XML for optimized packages
> +        if (len(eq)):
> +            if len(diff.getArchs()) != releaseArchHash[release]:
> +                archDependCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Architecture depended section", "operator" : "AND"})
> +
> +                supportedArchCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Supported architectures section", "operator" : "OR"})
> +                for arch in diff.getArchs():
> +                    supportedArchCriteria.appendChild ( __createXMLElement 
> ("criterion", attrs = {"test_ref" : __createTest("arch", arch), "comment" : 
> "%s architecture" % arch}))
> +                    archDependCriteria.appendChild (supportedArchCriteria)
> +
> +            packageCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Packages section", "operator" : "OR"})
> +            for bpkg in eq.keys():
> +                packageCriteria.appendChild ( __createXMLElement 
> ("criterion", attrs = {"test_ref" : __createDPKGTest(bpkg, eq[bpkg]), 
> "comment" : "%s DPKG is earlier than %s" % (bpkg, eq[bpkg])}))
> +
> +            if len(diff.getArchs()) != releaseArchHash[release]:
> +                archDependCriteria.appendChild (packageCriteria)
> +                archCriteria.appendChild (archDependCriteria)
> +            else:
> +                archCriteria.appendChild (packageCriteria)
> +
> +    # Generate XML for all other packages
> +    if len(di):
> +        archDependCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Architecture depended section", "operator" : "AND"})
> +
> +        for (key, value) in di.iteritems():
> +            supportedPlatformCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Supported platform section", "operator" : "AND"})
> +            supportedPlatformCriteria.appendChild ( __createXMLElement 
> ("criterion", attrs = {"test_ref" : __createTest("arch", key), "comment" : 
> "%s architecture" % key}))
> +
> +            packageCriteria = __createXMLElement ("criteria", 
> attrs={"comment" : "Packages section", "operator" : "OR"})
> +
> +            for bpkg in di[key].keys():
> +                packageCriteria.appendChild ( __createXMLElement 
> ("criterion", attrs = {"test_ref" : __createDPKGTest(bpkg, di[key][bpkg]), 
> "comment" : "%s DPKG is earlier than %s" % (bpkg, di[key][bpkg])}))
> +                supportedPlatformCriteria.appendChild (packageCriteria)
> +
> +        archDependCriteria.appendChild (supportedPlatformCriteria)
> +        archCriteria.appendChild (archDependCriteria)
> +
> +    softwareCriteria.appendChild (archCriteria)
> +
> +    return (softwareCriteria)
>  
>  def createDefinition (dsa, dsaref):
> -     """ Generate OVAL header of Definition tag
> -     
> -             Print general informaton about OVAL definition. Use 
> createPlatformDefinition for generate criteria 
> -             sections for each affected release.
> -             
> -             Argument keywords:
> -             dsa -- DSA dentificator
> -             dsaref -- DSA parsed data
> -     """     
> -     if not dsaref.has_key("release"):
> -             logging.log(logging.WARNING, "DSA %s: Release definition not 
> well formatted. Ignoring this DSA." % dsa)
> -             raise DSAFormatException
> -             
> -     if not dsaref.has_key("packages"):
> -             logging.log(logging.WARNING, "DSA %s: Package information 
> missed. Ignoring this DSA." % dsa)
> -             dsaref["packages"] = ""
> -
> -     if not dsaref.has_key("description"):
> -             logging.log(logging.WARNING, "DSA %s: Description information 
> missed." % dsa)
> -             dsaref["description"] = ""
> -
> -     if not dsaref.has_key("moreinfo"):
> -             logging.log(logging.WARNING, "DSA %s: Moreinfo information 
> missed." % dsa)
> -             dsaref["moreinfo"] = ""
> -     
> -     if not dsaref.has_key("secrefs"):
> -             logging.log(logging.WARNING, "DSA %s: Secrefs information 
> missed." % dsa)
> -             dsaref["secrefs"] = ""
> -
> -     doc = xml.dom.minidom.Document ()
> -     
> -     ### Definition block: Metadata, Notes, Criteria
> -     ### TODO: Replace DSA id with unique id
> -     definition = __createXMLElement ("definition", attrs = {"id" : 
> "oval:org.debian:def:%s" % __trimzero(dsa), "version" : "1", "class" : 
> "vulnerability"})
> -     
> -     ### Definition : Metadata : title, affected, reference, description ###
> -     metadata = __createXMLElement ("metadata")
> -     metadata.appendChild (__createXMLElement ("title", 
> dsaref["description"]))
> -
> -     ### Definition : Metadata : Affected : platform, product ###
> -     affected = __createXMLElement ("affected", attrs = {"family" : "unix"})
> -     for platform in dsaref["release"]:
> -             affected.appendChild ( __createXMLElement ("platform", "Debian 
> GNU/Linux %s" % platform))
> -     affected.appendChild ( __createXMLElement ("product", 
> dsaref.get("packages")))
> -             
> -     metadata.appendChild (affected)
> -     ### Definition : Metadata : Affected : END ###
> -
> -     refpatern = re.compile (r'((CVE|CAN)-[\d-]+)')
> -     for ref in dsaref.get("secrefs").split(" "):
> -             result = refpatern.search(ref)
> -             if result:
> -                     (ref_id, source) = result.groups()
> -                     metadata.appendChild ( __createXMLElement ("reference", 
> attrs = {"source" : source, "ref_id" : ref_id, "ref_url" : 
> "http://cve.mitre.org/cgi-bin/cvename.cgi?name=%s"; % ref_id}) )
> -     
> -     #TODO: move this info to other place
> -     metadata.appendChild ( __createXMLElement ("description", "What 
> information can i put there?"))
> -     debianMetadata = __createXMLElement ("debian")
> -     if dsaref.has_key("date"):
> -             debianMetadata.appendChild ( __createXMLElement ("date", 
> dsaref["date"]) )
> -     debianMetadata.appendChild ( __createXMLElement ("moreinfo", 
> dsaref["moreinfo"]) )
> -     metadata.appendChild (debianMetadata)
> -     definition.appendChild ( metadata )
> -
> -     ### Definition : Criteria ###
> -     if len(dsaref["release"]) > 1:
> -             #f we have more than one release - generate additional criteria 
> section
> -             platformCriteria = __createXMLElement ("criteria", attrs = 
> {"comment" : "Platform section", "operator" : "OR"})
> -             definition.appendChild (platformCriteria)
> -     else:
> -             platformCriteria = definition
> -     
> -     for platform in dsaref["release"]:
> -             data = dsaref["release"][platform]
> -             platformCriteria.appendChild 
> (createPlatformDefinition(platform, data, dsa))
> -             
> -     ### Definition : Criteria END ###
> -
> -     return (definition)
> -
> -def createOVALDefinitions (dsaref):
> -     """ Generate XML OVAL definition tree for range of DSA
> -     
> -             Generate namespace section and use other functions to generate 
> definitions,
> -             tests, objects and states subsections.
> -             
> -             return -- Generated OVAL XML definition 
> -     """
> -     doc = xml.dom.minidom.Document ()
> -
> -     root = __createXMLElement ("oval_definitions", 
> -                     attrs= {
> -                             "xsi:schemaLocation" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#independent 
> independent-definitions-schema.xsd 
> http://oval.mitre.org/XMLSchema/oval-definitions-5#linux 
> linux-definitions-schema.xsd 
> http://oval.mitre.org/XMLSchema/oval-definitions-5#unix 
> unix-definitions-schema.xsd 
> http://oval.mitre.org/XMLSchema/oval-definitions-5 
> oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 
> oval-common-schema.xsd",
> -                             "xmlns:xsi"             : 
> "http://www.w3.org/2001/XMLSchema-instance";,
> -                             "xmlns:ind-def "        : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#independent";,
> -                             "xmlns:linux-def" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#linux";,
> -                             "xmlns:oval-def" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5";,
> -                             "xmlns:unix-def" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#unix";,
> -                             "xmlns"                                 : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5";,
> -                             "xmlns:oval"            : 
> "http://oval.mitre.org/XMLSchema/oval-common-5";
> -                     }
> -                     )
> -     doc.appendChild (root)
> -     root.appendChild ( __createGeneratorHeader () )
> -     
> -     definitions = doc.createElement ("definitions")
> -     
> -     keyids = dsaref.keys()
> -     keyids.sort()
> -     for dsa in keyids:
> -             try:
> -                     definitions.appendChild (createDefinition(dsa, 
> dsaref[dsa]))
> -             except DSAFormatException:
> -                     logging.log (logging.WARNING, "DSA %s: Bad data file. 
> Ignoring this DSA." % dsa)
> -                     
> -     root.appendChild (definitions)
> -     
> -     root.appendChild(tests)
> -     root.appendChild(objects)
> -     root.appendChild(states)
> +    """ Generate OVAL header of Definition tag
> +
> +        Print general information about OVAL definition. Use 
> createPlatformDefinition for generate criteria
> +        sections for each affected release.
> +
> +        Argument keywords:
> +        dsa -- DSA identifier
> +        dsaref -- DSA parsed data
> +    """
> +
> +    if not dsaref.has_key("release"):
> +        logging.log(logging.WARNING, "DSA %s: Release definition not well 
> formatted. Ignoring this DSA." % dsa)
> +        raise DSAFormatException
> +
> +    if not dsaref.has_key("packages"):
> +        logging.log(logging.WARNING, "DSA %s: Package information missed. 
> Ignoring this DSA." % dsa)
> +        dsaref["packages"] = ""
> +
> +    if not dsaref.has_key("description"):
> +        logging.log(logging.WARNING, "DSA %s: Description information 
> missed." % dsa)
> +        dsaref["description"] = ""
> +
> +    if not dsaref.has_key("moreinfo"):
> +        logging.log(logging.WARNING, "DSA %s: Moreinfo information missed." 
> % dsa)
> +        dsaref["moreinfo"] = ""
> +
> +    if not dsaref.has_key("secrefs"):
> +        logging.log(logging.WARNING, "DSA %s: Secrefs information missed." % 
> dsa)
> +        dsaref["secrefs"] = ""
> +
> +    doc = xml.dom.minidom.Document ()
> +
> +    ### Definition block: Metadata, Notes, Criteria
> +    ### TODO: Replace DSA id with unique id
> +    definition = __createXMLElement ("definition", attrs = {"id" : 
> "oval:org.debian:def:%s" % __trimzero(dsa), "version" : "1", "class" : 
> "vulnerability"})
> +
> +    ### Definition : Metadata : title, affected, reference, description ###
> +    metadata = __createXMLElement ("metadata")
> +    metadata.appendChild (__createXMLElement ("title", 
> dsaref["description"]))
> +
> +    ### Definition : Metadata : Affected : platform, product ###
> +    affected = __createXMLElement ("affected", attrs = {"family" : "unix"})
> +    for platform in dsaref["release"]:
> +        affected.appendChild ( __createXMLElement ("platform", "Debian 
> GNU/Linux %s" % platform))
> +    affected.appendChild ( __createXMLElement ("product", 
> dsaref.get("packages")))
> +
> +    metadata.appendChild (affected)
> +    ### Definition : Metadata : Affected : END ###
> +
> +    refpatern = re.compile (r'((CVE|CAN)-[\d-]+)')
> +    for ref in dsaref.get("secrefs").split(" "):
> +        result = refpatern.search(ref)
> +        if result:
> +            (ref_id, source) = result.groups()
> +            metadata.appendChild ( __createXMLElement ("reference", attrs = 
> {"source" : source, "ref_id" : ref_id, "ref_url" : 
> "http://cve.mitre.org/cgi-bin/cvename.cgi?name=%s"; % ref_id}) )
> +
> +    #TODO: move this info to other place
> +    metadata.appendChild ( __createXMLElement ("description", "What 
> information can i put there?"))
> +    debianMetadata = __createXMLElement ("debian")
> +    if dsaref.has_key("date"):
> +        debianMetadata.appendChild ( __createXMLElement ("date", 
> dsaref["date"]) )
> +    debianMetadata.appendChild ( __createXMLElement ("moreinfo", 
> dsaref["moreinfo"]) )
> +    metadata.appendChild (debianMetadata)
> +    definition.appendChild ( metadata )
> +
> +    ### Definition : Criteria ###
> +    if len(dsaref["release"]) > 1:
> +        #f we have more than one release - generate additional criteria 
> section
> +        platformCriteria = __createXMLElement ("criteria", attrs = 
> {"comment" : "Platform section", "operator" : "OR"})
> +        definition.appendChild (platformCriteria)
> +    else:
> +        platformCriteria = definition
> +
> +    for platform in dsaref["release"]:
> +        data = dsaref["release"][platform]
> +        platformCriteria.appendChild (createPlatformDefinition(platform, 
> data, dsa))
> +
> +    ### Definition : Criteria END ###
> +
> +    return (definition)
> +
> +def createOVALDefinitions(dsaref):
> +    """ Generate XML OVAL definition tree for range of DSA
> +
> +        Generate namespace section and use other functions to generate 
> definitions,
> +        tests, objects and states subsections.
> +
> +        return -- Generated OVAL XML definition
> +    """
> +    doc = xml.dom.minidom.Document ()
> +
> +    root = __createXMLElement ("oval_definitions",
> +            attrs= {
> +                "xsi:schemaLocation" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#independent 
> independent-definitions-schema.xsd 
> http://oval.mitre.org/XMLSchema/oval-definitions-5#linux 
> linux-definitions-schema.xsd 
> http://oval.mitre.org/XMLSchema/oval-definitions-5#unix 
> unix-definitions-schema.xsd 
> http://oval.mitre.org/XMLSchema/oval-definitions-5 
> oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 
> oval-common-schema.xsd",
> +                "xmlns:xsi"          : 
> "http://www.w3.org/2001/XMLSchema-instance";,
> +                "xmlns:ind-def "     : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#independent";,
> +                "xmlns:linux-def" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#linux";,
> +                "xmlns:oval-def" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5";,
> +                "xmlns:unix-def" : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5#unix";,
> +                "xmlns"                              : 
> "http://oval.mitre.org/XMLSchema/oval-definitions-5";,
> +                "xmlns:oval"                 : 
> "http://oval.mitre.org/XMLSchema/oval-common-5";
> +            }
> +            )
> +    doc.appendChild (root)
> +    root.appendChild ( __createGeneratorHeader () )
> +
> +    definitions = doc.createElement ("definitions")
> +
> +    keyids = dsaref.keys()
> +    keyids.sort()
> +    for dsa in keyids:
> +        try:
> +            definitions.appendChild (createDefinition(dsa, dsaref[dsa]))
> +        except DSAFormatException:
> +            logging.log (logging.WARNING, "DSA %s: Bad data file. Ignoring 
> this DSA." % dsa)
> +
> +    root.appendChild (definitions)
> +
> +    root.appendChild(tests)
> +    root.appendChild(objects)
> +    root.appendChild(states)
>  
> -     return doc
> +    return doc
>  
>  def printOVALDefinitions (doc):
> -     if doc.getElementsByTagName("definitions")[0].hasChildNodes():
> -                print doc.toprettyxml()
> +    if doc.getElementsByTagName("definitions")[0].hasChildNodes():
> +        print doc.toprettyxml()
> Binary files oval_old/oval/definition/generator.pyc and 
> oval/oval/definition/generator.pyc differ
> Binary files oval_old/oval/definition/__init__.pyc and 
> oval/oval/definition/__init__.pyc differ
> Binary files oval_old/oval/__init__.pyc and oval/oval/__init__.pyc differ
> diff -urN oval_old/oval/parser/dsa.py oval/oval/parser/dsa.py
> --- oval_old/oval/parser/dsa.py       2011-10-11 17:41:19.000000000 -0600
> +++ oval/oval/parser/dsa.py   2015-11-13 09:34:04.843882000 -0700
> @@ -9,6 +9,7 @@
>  #            <isvulnerable>
>  #            <fixed>
>  #
> +# (c) 2015 Nicholas Luedtke
>  # (c) 2007 Pavel Vinogradov     
>  # (c) 2004 Javier Fernandez-Sanguino                                         
>                                                          
>  # Licensed under the GNU General Public License version 2.
> @@ -17,105 +18,113 @@
>  import os
>  import logging
>  
> +
>  # Format of data files is:
> -#<define-tag pagetitle>DSA-###-# PACKAGE</define-tag>                        
>                                                                   
> -#<define-tag report_date>yyyy-mm-dd</define-tag>                             
>                                                                   
> -#<define-tag secrefs>CAN|CVE-XXXX-XXXX</define-tag>                          
>                                                                   
> -#<define-tag packages>PACKAGE</define-tag>                                   
>                                                                   
> -#<define-tag isvulnerable>yes|no</define-tag>                                
>                                                                   
> -#<define-tag fixed>yes|no</define-tag>  
> -def parseFile (path):
> -     """ Parse data file with information of Debian Security Advisories 
> +# <define-tag pagetitle>DSA-###-# PACKAGE</define-tag>
> +# <define-tag report_date>yyyy-mm-dd</define-tag>
> +# <define-tag secrefs>CAN|CVE-XXXX-XXXX</define-tag>
> +# <define-tag packages>PACKAGE</define-tag>
> +# <define-tag isvulnerable>yes|no</define-tag>
> +# <define-tag fixed>yes|no</define-tag>
> +def parseFile(path):
> +    """ Parse data file with information of Debian Security Advisories
>       
>       Keyword arguments:
>       path -- full path to data file
>       
>       return list (dsa id, tags and packages data)"""
> -     
> -
> -     data = {}
> -     deb_ver = None
> -     fdeb_ver = None
> -     
> -     filename = os.path.basename (path)
>  
> -     patern = re.compile(r'dsa-(\d+)')
> -     result = patern.search(filename)
> -     if result:
> -             dsa = result.groups()[0]
> -     else:
> -             logging.log(logging.WARNING, "File %s does not look like a 
> proper DSA, not checking" % filename)
> -             return (None)
> +    data = {}
> +    deb_ver = None
> +    fdeb_ver = None
> +
> +    filename = os.path.basename(path)
> +
> +    patern = re.compile(r'dsa-(\d+)')
> +    result = patern.search(filename)
> +
> +    if result:
> +        dsa = result.groups()[0]
> +
> +    else:
> +        logging.log(logging.WARNING,
> +                    "File %s does not look like a proper DSA, not checking" 
> % filename)
> +        return (None)
> +
> +    logging.log(logging.DEBUG, "Parsing DSA %s from file %s" % (dsa, 
> filename))
> +
> +    dsaFile = open(path)
> +
> +    for line in dsaFile:
> +        line = line.decode("ISO-8859-2")
> +        datepatern = re.compile(r'report_date>([\d-]+)</define-tag>')
> +        result = datepatern.search(line)
> +        if result:
> +            date = result.groups()[0]
> +            normDate = lambda (date): "-".join(
> +                [(len(p) > 1 and p or "0" + p) for p in date.split("-")])
> +            data["date"] = normDate(date)
> +
> +        refspatern = re.compile(r'secrefs>(.*?)</define-tag>')
> +        result = refspatern.search(line)
> +        if result:
> +            data["secrefs"] = result.groups()[0]
> +            logging.log(logging.DEBUG,
> +                        "Extracted security references: " + data["secrefs"])
> +
> +        pakpatern = re.compile(r'packages>(.*?)</define-tag>')
> +        result = pakpatern.search(line)
> +        if result:
> +            data["packages"] = result.groups()[0]
> +
> +        vulpatern = re.compile(r'isvulnerable>(.*?)</define-tag>')
> +        result = vulpatern.search(line)
> +        if result:
> +            data["vulnarable"] = result.groups()[0]
> +
> +        fixpatern = re.compile(r'fixed>(.*?)</define-tag>')
> +        result = fixpatern.search(line)
> +        if result:
> +            data["fixed"] = result.groups()[0]
> +
> +        versionpatern = re.compile(
> +            r'<h3>Debian GNU/Linux (\d.\d) \((.*?)\)</h3>')
> +        result = versionpatern.search(line)
> +        if result:
> +            fdeb_ver = result.groups()[0]
> +
> +        # Alternative format for data files
> +        versionpatern = re.compile(r'affected_release>([\d\.]+)<')
> +        result = versionpatern.search(line)
> +        if result:
> +            fdeb_ver = result.groups()[0]
> +
> +        if fdeb_ver:
> +            deb_ver = fdeb_ver
> +            fdeb_ver = None
> +            if data.has_key("release"):
> +                if data["release"].has_key(deb_ver):
> +                    logging.log(logging.WARNING,
> +                                "DSA %s: Found second files section for 
> release %s" % (
> +                                    dsa, deb_ver))
> +                else:
> +                    data["release"][deb_ver] = {}
> +            else:
> +                data["release"] = {deb_ver: {}}
> +
> +        # Binary packages are pushed into array
> +        # Those are prepended by fileurls
> +        # TODO: Packages do _NOT_ include epochs
> +        # (that should be fixed)
> +        if data.has_key("release") and deb_ver:
> +            urlpatern = re.compile(r'fileurl 
> [\w:/.\-+]+/([\w\-.+~]+)\.deb[^i]')
> +            result = urlpatern.search(line)
> +            if result:
> +                (package, version, architecture) = 
> result.groups()[0].split("_")
> +
> +                if data["release"][deb_ver].has_key(architecture):
> +                    data["release"][deb_ver][architecture][package] = version
> +                else:
> +                    data["release"][deb_ver][architecture] = {package: 
> version}
>  
> -     logging.log (logging.DEBUG, "Parsing DSA %s from file %s" % (dsa, 
> filename))
> -
> -     dsaFile = open(path)
> -     
> -     for line in dsaFile:
> -             line= line.decode ("ISO-8859-2")
> -             datepatern = re.compile (r'report_date>([\d-]+)</define-tag>')
> -             result = datepatern.search (line)
> -             if result:
> -                     date = result.groups()[0]
> -                     normDate = lambda (date): "-".join([(len(p) > 1 and p 
> or "0"+p) for p in date.split("-")])
> -                     data["date"] = normDate(date)
> -             
> -             refspatern = re.compile (r'secrefs>(.*?)</define-tag>')
> -             result = refspatern.search (line)
> -             if result:
> -                     data["secrefs"] = result.groups()[0]
> -                     logging.log(logging.DEBUG, "Extracted security 
> references: " + data["secrefs"])
> -
> -             pakpatern = re.compile (r'packages>(.*?)</define-tag>')
> -             result = pakpatern.search (line)
> -             if result:
> -                     data["packages"] = result.groups()[0]
> -
> -             vulpatern = re.compile (r'isvulnerable>(.*?)</define-tag>')
> -             result = vulpatern.search (line)
> -             if result:
> -                     data["vulnarable"] = result.groups()[0]
> -
> -             fixpatern = re.compile (r'fixed>(.*?)</define-tag>')
> -             result = fixpatern.search (line)
> -             if result:
> -                     data["fixed"] = result.groups()[0]
> -
> -             versionpatern = re.compile (r'<h3>Debian GNU/Linux (\d.\d) 
> \((.*?)\)</h3>')
> -             result = versionpatern.search (line)
> -             if result:
> -                     fdeb_ver = result.groups()[0]
> -
> -                # Alternative format for data files
> -             versionpatern = re.compile (r'affected_release>([\d\.]+)<')
> -             result = versionpatern.search (line)
> -             if result:
> -                     fdeb_ver = result.groups()[0]
> -                     
> -                if fdeb_ver:
> -                        deb_ver = fdeb_ver 
> -                        fdeb_ver = None
> -                     if data.has_key("release"):
> -                             if data["release"].has_key(deb_ver):
> -                                     logging.log(logging.WARNING, "DSA %s: 
> Found second files section for release %s" % (dsa, deb_ver))
> -                             else:
> -                                     data["release"][deb_ver] = {}
> -                     else:
> -                             data["release"] = {deb_ver: {}}
> -
> -             # Binary packages are pushed into array
> -             # Those are prepended by fileurls
> -             # TODO: Packages do _NOT_ include epochs 
> -             # (that should be fixed)
> -             if data.has_key("release") and deb_ver:
> -                     urlpatern = re.compile (r'fileurl 
> [\w:/.\-+]+/([\w\-.+~]+)\.deb[^i]')
> -                     result = urlpatern.search (line)
> -                     if result:
> -                             (package, version, architecture) = 
> result.groups()[0].split("_")
> -                                     
> -                             if 
> data["release"][deb_ver].has_key(architecture):
> -                                     
> data["release"][deb_ver][architecture][package] = version
> -                             else:
> -                                     data["release"][deb_ver][architecture] 
> = {package : version}
> -     
> -     return (dsa, data)
> +    return (dsa, data)
> Binary files oval_old/oval/parser/dsa.pyc and oval/oval/parser/dsa.pyc differ
> Binary files oval_old/oval/parser/__init__.pyc and 
> oval/oval/parser/__init__.pyc differ
> diff -urN oval_old/oval/parser/wml.py oval/oval/parser/wml.py
> --- oval_old/oval/parser/wml.py       2013-01-21 00:48:41.000000000 -0700
> +++ oval/oval/parser/wml.py   2015-11-06 08:50:30.632363000 -0700
> @@ -1,13 +1,14 @@
>  # -*- coding: utf-8 -*-
> -# oval.parser.wml - module to parse descriptions of 
> +# oval.parser.wml - module to parse descriptions of
>  # Debian Security Advisories stored in wml format.
>  # Extrected tags:
>  #    <description>
>  #            <moreinfo>- Paragraphs before descriptions of
>  # each release status
>  #
> -# (c) 2007 Pavel Vinogradov   
> -# (c) 2004 Javier Fernandez-Sanguino                                         
>                                                            
> +# (c) 2015 Nicholas Luedtke
> +# (c) 2007 Pavel Vinogradov
> +# (c) 2004 Javier Fernandez-Sanguino
>  # Licensed under the GNU General Public License version 2.
>  
>  import re
> @@ -15,76 +16,111 @@
>  import sys
>  import logging
>  
> +DEBIAN_VERSION = {"wheezy" : "7.0", "jessie" : "8.2", "stretch" : "9.0",
> +                  "sid" : "9.0", "etch" : "4.0", "squeeze":"6.0", 
> "lenny":"5.0"}
> +
>  # Format of wml files is:
>  #<define-tag description>DESCRIPTION</define-tag>
>  #<define-tag moreinfo>Multiline information</define-tag>
>  def parseFile (path):
> -     """ Parse wml file with description of Debian Security Advisories 
> -     
> -     Keyword arguments:
> -     path -- full path to wml file
> -     
> -     return list (dsa id, tags data)"""
> -     
> -     data = {}
> -     moreinfo = False
> -     
> -     filename = os.path.basename (path)
> -     
> -     patern = re.compile(r'dsa-(\d+)')
> -     result = patern.search(filename)
> -     if result:
> -             dsa = result.groups()[0]
> -     else:
> -             logging.log(logging.WARNING, "File %s does not look like a 
> proper DSA wml description, not checking" % filename)
> -             return (None)
> -     
> -     logging.log (logging.DEBUG, "Parsing information for DSA %s from wml 
> file %s" % (dsa, filename))
> -     
> -     try:
> -             wmlFile = open(path)
> -             
> -             for line in wmlFile:
> -                     line= line.decode ("ISO-8859-2")
> -                             
> -                     descrpatern = re.compile 
> (r'description>(.*?)</define-tag>')
> -                     result = descrpatern.search (line)
> -                     if result:
> -                             data["description"] = result.groups()[0]
> -                             continue
> -                             
> -                     sinfopatern = re.compile (r'<define-tag moreinfo>(.*?)')
> -                     result = sinfopatern.search (line)
> -                     if result:
> -                             moreinfo = True
> -                             data["moreinfo"] = result.groups()[0] 
> -                             continue
> -                     
> -                     einfopatern = re.compile (r'</define-tag>')
> -                     if moreinfo and einfopatern.search (line):
> -                             data["moreinfo"] = 
> __parseMoreinfo(data["moreinfo"])
> -                             moreinfo = False
> -                             continue
> -                     
> -                     if moreinfo:
> -                             data["moreinfo"] += line
> -                             continue
> -                     
> -     except IOError:
> -             logging.log (logging.ERROR, "Can't work with file %s" % path)
> -     
> -     return (dsa, data)
> +    """ Parse wml file with description of Debian Security Advisories
> +
> +    Keyword arguments:
> +    path -- full path to wml file
> +
> +    return list (dsa id, tags data)"""
> +
> +    data = {}
> +    moreinfo = False
> +    pack_ver = ""
> +    deb_version = ""
> +    releases = {}
> +
> +    filename = os.path.basename (path)
> +
> +    patern = re.compile(r'dsa-(\d+)')
> +    result = patern.search(filename)
> +    if result:
> +        dsa = result.groups()[0]
> +    else:
> +        logging.log(logging.WARNING, "File %s does not look like a proper 
> DSA wml description, not checking" % filename)
> +        return (None)
> +
> +    logging.log (logging.DEBUG, "Parsing information for DSA %s from wml 
> file %s" % (dsa, filename))
> +
> +    try:
> +        wmlFile = open(path)
> +
> +        for line in wmlFile:
> +            line= line.decode ("ISO-8859-2")
> +
> +            descrpatern = re.compile (r'description>(.*?)</define-tag>')
> +            result = descrpatern.search (line)
> +            if result:
> +                data["description"] = result.groups()[0]
> +                continue
> +
> +            sinfopatern = re.compile (r'<define-tag moreinfo>(.*?)')
> +            result = sinfopatern.search (line)
> +            if result:
> +                moreinfo = True
> +                data["moreinfo"] = result.groups()[0]
> +                continue
> +
> +            einfopatern = re.compile (r'</define-tag>')
> +            if moreinfo and einfopatern.search (line):
> +                data["moreinfo"] = __parseMoreinfo(data["moreinfo"])
> +                moreinfo = False
> +                continue
> +
> +            if moreinfo:
> +                data["moreinfo"] += line
> +                #continue
> +
> +            dversion_pattern = re.compile(r'distribution \((.*?)\)')
> +            result = dversion_pattern.search(line)
> +            if result:
> +                deb_version = result.groups()[0]
> +
> +            new_version_pattern = re.compile(r'version (.*?).</p>')
> +            result = new_version_pattern.search(line)
> +            if result and deb_version != "":
> +                pack_ver = result.groups()[0]
> +                releases.update({DEBIAN_VERSION[deb_version]: {u"all": 
> {grabPackName(path) : pack_ver}}})
> +
> +
> +
> +    except IOError:
> +        logging.log (logging.ERROR, "Can't work with file %s" % path)
> +
> +    return dsa, data, releases
>  
>  def __parseMoreinfo (info):
> -     """ Remove unnecessary information form moreinfo tag"""
> +    """ Remove unnecessary information form moreinfo tag"""
> +
> +    p = re.compile ("<p>(.*?)</p>", re.DOTALL)
> +    paragraphs = [m.groups()[0]  for m in re.finditer(p, info)]
> +    result = ""
> +
> +    for par in paragraphs:
> +        if re.match(re.compile("For the .* distribution"), par):
> +            break
> +        result += "\n" + par
> +
> +    return result
> +
> +def grabPackName(path):
> +    """
> +    :param path: full path to wml file
> +    :return: string: Package Name
> +    """
>  
> -     p = re.compile ("<p>(.*?)</p>", re.DOTALL)
> -     paragraphs = [m.groups()[0]  for m in re.finditer(p, info)]
> -     result = ""
> -
> -     for par in paragraphs:
> -             if re.match(re.compile("For the .* distribution"), par):
> -                     break
> -             result += "\n" + par
> -     
> -     return result
> +    try:
> +        wmlFile = open(path)
> +        package_name = re.compile (r'We recommend that you upgrade your 
> (.*?) packages')
> +        for line in wmlFile:
> +            result = package_name.search(line)
> +            if result:
> +                return result.groups()[0]
> +    except IOError:
> +        logging.log (logging.ERROR, "Can't work with file %s" % path)
> Binary files oval_old/oval/parser/wml.pyc and oval/oval/parser/wml.pyc differ
> diff -urN oval_old/parseDsa2Oval.py oval/parseDsa2Oval.py
> --- oval_old/parseDsa2Oval.py 2011-10-12 15:14:55.000000000 -0600
> +++ oval/parseDsa2Oval.py     2015-11-13 11:13:33.923838000 -0700
> @@ -2,11 +2,11 @@
>  # -*- coding: utf-8 -*-
>  # Extracts the data DSA files and creates OVAL queries to
>  # be used with the OVAL query interpreter (see http://oval.mitre.org)
> -
> +# (c) 2015 Nicholas Luedtke
>  # (c) 2007 Pavel Vinogradov
>  # (c) 2004 Javier Fernandez-Sanguino                                         
>                                                                   
>  # Licensed under the GNU General Public License version 2.                   
>                                                                   
> -                                                                             
>                                                                   
> +
>  import os
>  import sys
>  import getopt
> @@ -18,89 +18,89 @@
>  
>  dsaref = {}
>  
> +
>  def usage (prog = "parse-wml-oval.py"):
> -     """Print information about script flags and options"""
> +    """Print information about script flags and options"""
>  
> -     print """
> -usage: %s [vh] [-d <directory>]
> -\t-d\twhich directory use for dsa definition search
> -\t-v\tverbose mode
> -\t-h\tthis help
> -     """ % prog
> -   
> -def printdsas (dsaref):
> +    print """usage: %s [vh] [-d <directory>]\t-d\twhich directory use for
> +    dsa definition search\t-v\tverbose mode\t-h\tthis help""" % prog
> +
> +def printdsas(dsaref):
>      """ Generate and print OVAL Definitions for collected DSA information """
> -    
> +
>      ovalDefinitions = oval.definition.generator.createOVALDefinitions 
> (dsaref)
>      oval.definition.generator.printOVALDefinitions (ovalDefinitions)
>  
>  def parsedirs (directory, postfix, depth):
> -     """ Recursive search directory for DSA files contain postfix in their 
> names.
> -
> -             For this files called oval.parser.dsa.parseFile() for 
> extracting DSA information.
> -     """
> -
> -     if depth == 0:
> -             logging.log(logging.DEBUG, "Maximum depth reached at directory 
> " + directory)
> -             return (0)
> +    """ Recursive search directory for DSA files contain postfix in their 
> names.
> +    For this files called oval.parser.dsa.parseFile() for extracting DSA
> +    information.
> +    """
> +
> +    if depth == 0:
> +        logging.log(logging.DEBUG, "Maximum depth reached at directory " + 
> directory)
> +        return (0)
>       
> -     for file in os.listdir (directory):
> -             
> -             path = "%s/%s" % (directory, file)
> -             
> -             logging.log (logging.DEBUG, "Checking %s (for %s at %s)" % 
> (file, postfix, depth))
> +    for file in os.listdir (directory):
>               
> -             if os.access(path, os.R_OK) and os.path.isdir (path) and not 
> os.path.islink (path) and file[0] != '.':
> -                     logging.log(logging.DEBUG, "Entering directory " + path)
> -                     parsedirs (path, postfix, depth-1)
> +        path = "%s/%s" % (directory, file)
> +        logging.log (logging.DEBUG, "Checking %s (for %s at %s)" % (file, 
> postfix, depth))
>               
> +        if os.access(path, os.R_OK) and os.path.isdir (path) and not 
> os.path.islink (path) and file[0] != '.':
> +            logging.log(logging.DEBUG, "Entering directory " + path)
> +            parsedirs (path, postfix, depth-1)
> +
>          #Parse DSA data files
> -             if os.access(path, os.R_OK) and file.endswith(postfix) and 
> file[0] != '.' and file[0] != '#':
> -                     result = dsa.parseFile (path)
> -                     if result:
> -                             if dsaref.has_key (result[0]):
> -                                     for (k, v) in result[1].iteritems():
> -                                             dsaref[result[0]][k] = v
> -                             else:
> -                                     dsaref[result[0]] = result[1]
> -             
> +        if os.access(path, os.R_OK) and file.endswith(postfix) and file[0] 
> != '.' and file[0] != '#':
> +            result = dsa.parseFile(path)
> +            if result:
> +                if dsaref.has_key(result[0]):
> +                    for (k, v) in result[1].iteritems():
> +                        dsaref[result[0]][k] = v
> +                else:
> +                    dsaref[result[0]] = result[1]
> +
>          #Parse DSA wml descriptions
> -             if os.access(path, os.R_OK) and file.endswith(".wml") and 
> file[0] != '.' and file[0] != '#':
> -                     result = wml.parseFile(path)
> -                     if result:
> -                             if dsaref.has_key (result[0]):
> -                                     for (k, v) in result[1].iteritems():
> -                                             dsaref[result[0]][k] = v
> -                             else:
> -                                     dsaref[result[0]] = result[1]
> -                                                                     
> -     return 0
> +        if os.access(path, os.R_OK) and file.endswith(".wml") and file[0] != 
> '.' and file[0] != '#':
> +            result = wml.parseFile(path)
> +            if result:
> +                if dsaref.has_key(result[0]):
> +                    for (k, v) in result[1].iteritems():
> +                        dsaref[result[0]][k] = v
> +                    if not dsaref[result[0]].has_key("release"):
> +                        dsaref[result[0]]['release']=result[2]
> +                else:
> +                    dsaref[result[0]] = result[1]
> +                    dsaref[result[0]]['release']=result[2]
> +
> +    return 0
>  
>  if __name__ == "__main__":
> -    
> +
>      # Parse cmd options with getopt
>      opts = {}
> -    
> +
>      #By default we search dsa definitions from current directory, but -d 
> option override this
>      opts['-d'] = "./"
> -    
> +
>      try:
>          opt, args = getopt.getopt (sys.argv[1:], 'vhd:')
>      except getopt.GetoptError:
>          usage ()
>          sys.exit(1)
> -    
> +
>      for key, value in opt:
>          opts[key] = value
> -    
> +
>      if opts.has_key ('-h'):
>          usage()
>          sys.exit(0)
> -        
> +
>      if opts.has_key('-v'):
>          logging.basicConfig(level=logging.DEBUG)
> -        
> +
>      logging.basicConfig(level=logging.WARNING)
> -        
> +
>      parsedirs (opts['-d'], '.data', 2)
> +
>      printdsas(dsaref)
> diff -urN oval_old/parseJSON2Oval.py oval/parseJSON2Oval.py
> --- oval_old/parseJSON2Oval.py        1969-12-31 17:00:00.000000000 -0700
> +++ oval/parseJSON2Oval.py    2015-11-13 13:16:42.523783000 -0700
> @@ -0,0 +1,191 @@
> +#!/usr/bin/python
> +# -*- coding: utf-8 -*-
> +# Extracts the data from the security tracker and creates OVAL queries to
> +# be used with the OVAL query interpreter (see http://oval.mitre.org)
> +
> +# (c) 2015 Nicholas Luedtke
> +# Licensed under the GNU General Public License version 2.                   
>                                                                   
> +
> +import os
> +from subprocess import call
> +import sys
> +import logging
> +import argparse
> +import json
> +from datetime import date
> +import oval.definition.generator
> +from oval.parser import dsa
> +from oval.parser import wml
> +
> +
> +dsaref = {}
> +
> +# TODO: these may need changed or reworked.
> +DEBIAN_VERSION = {"wheezy" : "7.0", "jessie" : "8.2", "stretch" : "9.0",
> +                  "sid" : "9.0", "etch" : "4.0", "squeeze":"6.0", 
> "lenny":"5.0"}
> +
> +def usage (prog = "parse-wml-oval.py"):
> +    """Print information about script flags and options"""
> +
> +    print """usage: %s [vh] [-d <directory>]\t-d\twhich directory use for
> +    dsa definition search\t-v\tverbose mode\t-h\tthis help""" % prog
> +
> +
> +def printdsas(dsaref):
> +    """ Generate and print OVAL Definitions for collected DSA information """
> +
> +    ovalDefinitions = oval.definition.generator.createOVALDefinitions 
> (dsaref)
> +    oval.definition.generator.printOVALDefinitions (ovalDefinitions)
> +
> +
> +def parsedirs (directory, postfix, depth):
> +    """ Recursive search directory for DSA files contain postfix in their 
> names.
> +    For this files called oval.parser.dsa.parseFile() for extracting DSA
> +    information.
> +    """
> +    for file in os.listdir (directory):
> +             
> +        path = "%s/%s" % (directory, file)
> +        logging.log (logging.DEBUG, "Checking %s (for %s at %s)" % (file, 
> postfix, depth))
> +             
> +        if os.access(path, os.R_OK) and os.path.isdir (path) and not 
> os.path.islink (path) and file[0] != '.':
> +            logging.log(logging.DEBUG, "Entering directory " + path)
> +            parsedirs (path, postfix, depth-1)
> +
> +        #Parse DSA data files
> +        if os.access(path, os.R_OK) and file.endswith(postfix) and file[0] 
> != '.' and file[0] != '#':
> +            result = dsa.parseFile(path)
> +            if result:
> +                if dsaref.has_key(result[0]):
> +                    for (k, v) in result[1].iteritems():
> +                        dsaref[result[0]][k] = v
> +                else:
> +                    dsaref[result[0]] = result[1]
> +
> +        #Parse DSA wml descriptions
> +        if os.access(path, os.R_OK) and file.endswith(".wml") and file[0] != 
> '.' and file[0] != '#':
> +            result = wml.parseFile(path)
> +            if result:
> +                if dsaref.has_key(result[0]):
> +                    for (k, v) in result[1].iteritems():
> +                        dsaref[result[0]][k] = v
> +                    if not dsaref[result[0]].has_key("release"):
> +                        dsaref[result[0]]['release']=result[2]
> +                else:
> +                    dsaref[result[0]] = result[1]
> +                    dsaref[result[0]]['release']=result[2]
> +    return 0
> +
> +
> +def parseJSON(json_data, id_num):
> +    """
> +    Parse the JSON data and extract information needed for OVAL definitions
> +    :param id_num: int id number to start at for defintions
> +    :param json_data: Json_Data
> +    :return:
> +    """
> +    today = date.today()
> +    logging.log(logging.DEBUG, "Start of JSON Parse.")
> +    d_num = id_num
> +    for package in json_data:
> +        logging.log(logging.DEBUG, "Parsing package %s" % package)
> +        for CVE in json_data[package]:
> +            logging.log(logging.DEBUG, "Getting releases for %s" % CVE)
> +            release = {}
> +            for rel in json_data[package][CVE]['releases']:
> +                if json_data[package][CVE]['releases'][rel]['status'] != \
> +                        'resolved':
> +                    fixed_v = '0'
> +                    f_str = 'no'
> +                else:
> +                    fixed_v = 
> json_data[package][CVE]['releases'][rel]['fixed_version']
> +                    f_str = 'yes'
> +                release.update({DEBIAN_VERSION[rel]: {u'all': {
> +                    package: fixed_v}}})
> +
> +                dsaref.update({str(d_num): {"packages": package,
> +                                           'description': "",
> +                                    'vulnerable': "yes",
> +                                    'date': str(today.isoformat()),
> +                                    'fixed': f_str, 'moreinfo': "",
> +                                    'release': release, 'secrefs': CVE}})
> +                logging.log(logging.DEBUG, "Created entry in dsaref %s" % 
> d_num)
> +                d_num += 1
> +
> +
> +def get_json_data(json_file):
> +    """
> +    Retrieves JSON formatted data from a file.
> +    :param json_file:
> +    :return: JSON data (dependent on the file loaded, usually a dictionary.)
> +    """
> +    logging.log(logging.DEBUG, "Extracting JSON file %s" % json_file)
> +    with open(json_file, "r") as json_d:
> +        d = json.load(json_d)
> +    return d
> +
> +
> +def main(args):
> +    """
> +    Main function for parseJSON2Oval.py
> +    :param args:
> +    :return:
> +    """
> +
> +    if args['verbose']:
> +        logging.basicConfig(level=logging.DEBUG)
> +    else:
> +        logging.basicConfig(level=logging.WARNING)
> +
> +    # unpack args
> +
> +    json_file = args['JSONfile']
> +    temp_file = args['tmp']
> +    id_num = args['id']
> +
> +    if json_file:
> +        json_data = get_json_data(json_file)
> +    else:
> +        logging.log(logging.DEBUG, "Preparing to download JSONfile")
> +        if os.path.isfile(temp_file):
> +            logging.log(logging.WARNING, "Removing file %s" % temp_file)
> +            os.remove(temp_file)
> +        logging.log(logging.DEBUG, "Issuing wget for JSON file")
> +        args = ['wget', 
> 'https://security-tracker.debian.org/tracker/data/json',
> +                '-O', temp_file]
> +        call(args)
> +        logging.log(logging.DEBUG, "File %s received" % temp_file)
> +        json_data = get_json_data(temp_file)
> +        if os.path.isfile(temp_file):
> +            logging.log(logging.DEBUG, "Removing file %s" % temp_file)
> +            os.remove(temp_file)
> +
> +    parseJSON(json_data, id_num)
> +    #parsedirs (opts['-d'], '.data', 2)
> +
> +    printdsas(dsaref)
> +
> +if __name__ == "__main__":
> +    PARSER = argparse.ArgumentParser(description='Generates oval definitions 
> '
> +                                                 'from the JSON file used to 
> '
> +                                                 'build the Debian Security '
> +                                                 'Tracker.')
> +    PARSER.add_argument('-v', '--verbose', help='Verbose Mode',
> +                        action="store_true")
> +    PARSER.add_argument('-j', '--JSONfile', type=str,
> +                        help='Local JSON file to use. This will use a local '
> +                             'copy of the JSON file instead of downloading 
> from'
> +                             ' it from the server. default=none', 
> default=None)
> +    PARSER.add_argument('-t', '--tmp', type=str,
> +                        help='Temporary file to download JSON file to. 
> Warning:'
> +                             ' if this file already exists it will be 
> removed '
> +                             'prior to downloading the JSON file. default= '
> +                             './DebSecTrackTMP.t', 
> default='./DebSecTrackTMP.t')
> +    PARSER.add_argument('--id', type=int,
> +                        help='id number to start defintions at. default=100',
> +                        default=100)
> +    ARGS = vars(PARSER.parse_args())
> +    main(ARGS)
> +
> +
> +

Reply via email to