Mercurial > farol > farolluz
annotate farolluz/parsers/cvrf.py @ 9:4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
author | Benoît Allard <benoit.allard@greenbone.net> |
---|---|
date | Wed, 08 Oct 2014 12:44:20 +0200 |
parents | d62264a643fb |
children | dcc946b30343 |
rev | line source |
---|---|
0 | 1 # -*- coding: utf-8 -*- |
2 # Description: | |
3 # Methods for parsing CVRF documents | |
4 # | |
5 # Authors: | |
6 # BenoƮt Allard <benoit.allard@greenbone.net> | |
7 # | |
8 # Copyright: | |
9 # Copyright (C) 2014 Greenbone Networks GmbH | |
10 # | |
11 # This program is free software; you can redistribute it and/or | |
12 # modify it under the terms of the GNU General Public License | |
13 # as published by the Free Software Foundation; either version 2 | |
14 # of the License, or (at your option) any later version. | |
15 # | |
16 # This program is distributed in the hope that it will be useful, | |
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 # GNU General Public License for more details. | |
20 # | |
21 # You should have received a copy of the GNU General Public License | |
22 # along with this program; if not, write to the Free Software | |
23 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
24 | |
25 """\ | |
26 Methods for parsing of CVRF Documents | |
27 """ | |
28 | |
29 from __future__ import print_function | |
30 | |
31 import re | |
32 import textwrap | |
33 import xml.etree.ElementTree as ET | |
34 from datetime import datetime, timedelta | |
35 | |
36 try: | |
37 from datetime import timezone | |
38 except ImportError: | |
39 from ..py2 import FixedTimeZone as timezone | |
40 | |
41 from ..cvrf import (CVRF, CVRFPublisher, CVRFTracking, CVRFRevision, CVRFNote, | |
42 CVRFAcknowledgment, CVRFProductBranch, CVRFFullProductName, CVRFGenerator, | |
43 CVRFRelationship, CVRFVulnerability, CVRFVulnerabilityID, CVRFThreat, | |
44 CVRFProductStatus, CVRFCVSSSet, CVRFReference, CVRFRemediation, CVRFGroup, | |
1
d47e1164740f
Add support for AggregateSeverity
Benoît Allard <benoit.allard@greenbone.net>
parents:
0
diff
changeset
|
45 CVRFInvolvement, CVRFCWE, CVRFTrackingID, CVRFAggregateSeverity) |
0 | 46 |
47 NAMESPACES = { | |
48 'cvrf': "http://www.icasi.org/CVRF/schema/cvrf/1.1", | |
49 'prod': "http://www.icasi.org/CVRF/schema/prod/1.1", | |
50 'vuln': "http://www.icasi.org/CVRF/schema/vuln/1.1", | |
51 'xml': "http://www.w3.org/XML/1998/namespace", | |
52 } | |
53 | |
54 | |
55 def UN(ns, name): | |
56 """ UN for Universal Name """ | |
57 return "{%s}%s" % (NAMESPACES[ns], name) | |
58 | |
59 | |
60 def parseVersion(string): | |
61 return tuple(int(i) for i in string.split('.')) | |
62 | |
63 | |
64 def parseDate(string): | |
65 m = re.match('(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:([+-])(\d{2}):(\d{2})|(Z))?', string) | |
66 if (m.group(7) is None) or (m.group(7) == 'Z'): | |
67 tzhours = 0 | |
68 tzmin = 0 | |
69 else: | |
70 tzhours = int(m.group(8)) | |
71 if m.group(7) == '-': | |
72 tzhours = - tzhours | |
73 tzmin = int(m.group(9)) | |
74 return datetime(int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4)), int(m.group(5)), int(m.group(6)), tzinfo=timezone(timedelta(hours=tzhours, minutes=tzmin))) | |
75 | |
76 | |
77 def parseNote(elem): | |
78 return CVRFNote( | |
79 elem.attrib['Type'], | |
80 int(elem.attrib['Ordinal']), | |
81 textwrap.dedent(elem.text).strip(), | |
82 elem.attrib.get('Title'), | |
83 elem.attrib.get('Audience') | |
84 ) | |
85 | |
86 | |
87 def parseReference(elem, ns='cvrf'): | |
88 """ ns is the current namespace """ | |
89 return CVRFReference( | |
90 elem.findtext(UN(ns, 'URL')).strip(), | |
91 textwrap.dedent(elem.findtext(UN(ns, 'Description'))).strip(), | |
92 elem.attrib.get('Type') | |
93 ) | |
94 | |
95 | |
96 def parseAcknowledgment(elem, ns='cvrf'): | |
9
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
97 names = [] |
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
98 for cvrfname in elem.findall(UN(ns, 'Name')): |
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
99 names.append(cvrfname.text.strip()) |
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
100 orgs = [] |
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
101 for cvrforg in elem.findall(UN(ns, 'Organization')): |
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
102 orgs.append(cvrforg.text.strip()) |
0 | 103 return CVRFAcknowledgment( |
9
4c6e15514a6d
Parse Name and Organization in a Acknowledgment as multiple elements
Benoît Allard <benoit.allard@greenbone.net>
parents:
5
diff
changeset
|
104 names, orgs, |
0 | 105 elem.findtext(UN(ns, 'Description')), |
106 elem.findtext(UN(ns, 'URL')), | |
107 ) | |
108 | |
109 | |
110 def parseFullProductName(elem, parent): | |
111 return CVRFFullProductName( | |
112 elem.attrib['ProductID'], | |
113 elem.text.strip(), | |
114 parent, | |
115 cpe=elem.attrib.get('CPE') | |
116 ) | |
117 | |
118 | |
119 def parseProdBranch(elem, ptree, parentbranch=None): | |
120 """ Recursively parses the branches and the terminal productnames """ | |
121 fpncvrf = elem.find(UN('prod', 'FullProductName')) | |
122 if (parentbranch is not None) and (fpncvrf is not None): | |
123 # Don't process the products at the root of the tree | |
124 prod = parseFullProductName(fpncvrf, parentbranch) | |
125 ptree.addProduct(prod) | |
126 | |
127 if parentbranch is None: | |
128 parentbranch = ptree | |
129 for brcvrf in elem.findall(UN('prod', 'Branch')): | |
130 br = CVRFProductBranch(brcvrf.attrib['Type'], brcvrf.attrib['Name'], parentbranch) | |
131 # And go into recursion ... | |
132 br._childs = list(parseProdBranch(brcvrf, ptree, br)) | |
133 yield br | |
134 | |
135 | |
136 def parseVulnerability(elem): | |
137 vuln = CVRFVulnerability(int(elem.attrib['Ordinal'])) | |
138 | |
139 xmltitle = elem.findtext(UN('vuln', 'Title')) | |
140 if xmltitle is not None: | |
141 vuln.setTitle(xmltitle.strip()) | |
142 | |
143 xmlID = elem.find(UN('vuln', 'ID')) | |
144 if xmlID is not None: | |
145 vuln.setID(CVRFVulnerabilityID(xmlID.attrib['SystemName'], xmlID.text.strip())) | |
146 | |
147 for xmlnote in elem.findall('/'.join([UN('vuln', 'Notes'), UN('vuln', 'Note')])): | |
148 vuln.addNote(parseNote(xmlnote)) | |
149 | |
150 xmldiscoverydate = elem.findtext(UN('vuln', 'DiscoveryDate')) | |
151 if xmldiscoverydate is not None: | |
152 vuln.setDiscoveryDate(parseDate(xmldiscoverydate)) | |
153 xmlreleasedate = elem.findtext(UN('vuln', 'ReleaseDate')) | |
154 if xmlreleasedate is not None: | |
155 vuln.setReleaseDate(parseDate(xmlreleasedate)) | |
156 | |
157 for xmlinv in elem.findall('/'.join([UN('vuln', 'Involvements'), UN('vuln', 'Involvement')])): | |
158 involvement = CVRFInvolvement( | |
159 xmlinv.attrib['Party'], | |
160 xmlinv.attrib['Status'] | |
161 ) | |
162 xmldescr = xmlinv.findtext(UN('vuln', 'Description')) | |
163 if xmldescr is not None: | |
164 involvement.setDescription(textwrap.dedent(xmldescr).strip()) | |
165 vuln.addInvolvement(involvement) | |
166 | |
167 xmlcve = elem.findtext(UN('vuln', 'CVE')) | |
168 if xmlcve is not None: | |
169 vuln.setCVE(xmlcve.strip()) | |
170 | |
171 for xmlcwe in elem.findall(UN('vuln', 'CWE')): | |
172 vuln.addCWE(CVRFCWE( | |
173 xmlcwe.attrib['ID'], | |
174 xmlcwe.text.strip() | |
175 )) | |
176 | |
177 for xmlstatus in elem.findall('/'.join([UN('vuln', 'ProductStatuses'), UN('vuln', 'Status')])): | |
178 status = CVRFProductStatus(xmlstatus.attrib['Type']) | |
179 for xmlproductid in xmlstatus.findall(UN('vuln', 'ProductID')): | |
180 status.addProductID(xmlproductid.text.strip()) | |
181 | |
182 vuln.addProductStatus(status) | |
183 | |
184 for xmlthreat in elem.findall('/'.join([UN('vuln', 'Threats'), UN('vuln', 'Threat')])): | |
185 threat = CVRFThreat( | |
186 xmlthreat.attrib['Type'], | |
187 textwrap.dedent(xmlthreat.findtext(UN('vuln', 'Description'))).strip() | |
188 ) | |
189 xmldate = xmlthreat.findtext(UN('vuln', 'Date')) | |
190 if xmldate is not None: | |
191 threat.setDate(parseDate(xmldate)) | |
192 for xmlpid in xmlthreat.findall(UN('vuln', 'ProductID')): | |
193 threat.addProductID(xmlpid.text.strip()) | |
194 for xmlgid in xmlthreat.findall(UN('vuln', 'GroupID')): | |
195 threat.addGroupID(xmlgid.text.strip()) | |
196 | |
197 vuln.addThreat(threat) | |
198 | |
199 for xmlcvss in elem.findall('/'.join([UN('vuln', 'CVSSScoreSets'), UN('vuln', 'ScoreSet')])): | |
200 cvss_set = CVRFCVSSSet(float(xmlcvss.findtext(UN('vuln', 'BaseScore')).strip())) | |
201 xmltempscore = xmlcvss.findtext(UN('vuln', 'TemporalScore')) | |
202 if xmltempscore is not None: | |
203 cvss_set.setTemporalScore(float(xmltempscore.strip())) | |
204 xmlenvscore = xmlcvss.findtext(UN('vuln', 'EnvironmentalScore')) | |
205 if xmlenvscore is not None: | |
206 cvss_set.setEnvironmentalScore(float(xmlenvscore.strip())) | |
207 xmlvector = xmlcvss.findtext(UN('vuln', 'Vector')) | |
208 if xmlvector is not None: | |
209 cvss_set.setVector(xmlvector.strip()) | |
210 for xmlprodid in xmlcvss.findall(UN('vuln', 'ProductID')): | |
211 cvss_set.addProductID(xmlprodid.text.strip()) | |
212 | |
213 vuln.addCVSSSet(cvss_set) | |
214 | |
215 for xmlremediation in elem.findall('/'.join([UN('vuln', 'Remediations'), UN('vuln', 'Remediation')])): | |
216 remediation = CVRFRemediation( | |
217 xmlremediation.attrib['Type'], | |
218 textwrap.dedent(xmlremediation.findtext(UN('vuln', 'Description'))).strip() | |
219 ) | |
220 xmldate = xmlremediation.findtext(UN('vuln', 'Date')) | |
221 if xmldate is not None: | |
222 remediation.setDate(parseDate(xmldate)) | |
223 xmlentitlement = xmlremediation.findtext(UN('vuln', 'Entitlement')) | |
224 if xmlentitlement is not None: | |
225 remediation.setEntitlement(textwrap.dedent(xmlentitlement).strip()) | |
226 xmlurl = xmlremediation.findtext(UN('vuln', 'URL')) | |
227 if xmlurl is not None: | |
228 remediation.setURL(xmlurl.strip()) | |
229 for xmlpid in xmlremediation.findall(UN('vuln', 'ProductID')): | |
230 remediation.addProductID(xmlpid.text.strip()) | |
231 for xmlgid in xmlremediation.findall(UN('vuln', 'GroupID')): | |
232 remediation.addGroupID(xmlgid.text.strip()) | |
233 | |
234 vuln.addRemediation(remediation) | |
235 | |
236 for xmlref in elem.findall('/'.join([UN('vuln', 'References'), UN('vuln', 'Reference')])): | |
237 vuln.addReference(parseReference(xmlref, 'vuln')) | |
238 | |
239 for xmlack in elem.findall('/'.join([UN('vuln', 'Acknowledgments'), UN('vuln', 'Acknowledgment')])): | |
240 vuln.addAcknowledgment(parseAcknowledgment(xmlack, 'vuln')) | |
241 | |
242 return vuln | |
243 | |
244 | |
245 def parse(xml): | |
246 if hasattr(xml, 'read'): | |
247 xml = xml.read() | |
248 cvrfdoc = ET.fromstring(xml) | |
249 if cvrfdoc.tag != UN('cvrf', 'cvrfdoc'): | |
250 raise ValueError('Not a CVRF document !') | |
251 doc = CVRF( | |
252 cvrfdoc.findtext(UN('cvrf', 'DocumentTitle')).strip(), | |
253 cvrfdoc.findtext(UN('cvrf', 'DocumentType')).strip() | |
254 ) | |
5
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
255 |
0 | 256 cvrfpub = cvrfdoc.find(UN('cvrf', 'DocumentPublisher')) |
5
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
257 if cvrfpub is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
258 pub = CVRFPublisher(cvrfpub.attrib['Type'], cvrfpub.attrib.get('VendorID')) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
259 doc.setPublisher(pub) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
260 contact = cvrfpub.find(UN('cvrf', 'ContactDetails')) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
261 if contact is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
262 pub.setContact(contact.text.strip()) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
263 authority = cvrfpub.find(UN('cvrf', 'IssuingAuthority')) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
264 if authority is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
265 pub.setAuthority(authority.text.strip()) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
266 |
0 | 267 cvrftracking = cvrfdoc.find(UN('cvrf', 'DocumentTracking')) |
5
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
268 if cvrftracking is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
269 identification = CVRFTrackingID( |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
270 cvrftracking.findtext('/'.join([UN('cvrf', 'Identification'), UN('cvrf', 'ID')])).strip() |
0 | 271 ) |
5
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
272 for cvrfalias in cvrftracking.findall('/'.join([UN('cvrf', 'Identification'), UN('cvrf', 'Alias')])): |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
273 identification.addAlias(cvrfalias.text.strip()) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
274 tracking = CVRFTracking( |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
275 identification, |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
276 cvrftracking.findtext(UN('cvrf', 'Status')).strip(), |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
277 parseVersion(cvrftracking.findtext(UN('cvrf', 'Version')).strip()), |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
278 parseDate(cvrftracking.findtext(UN('cvrf', 'InitialReleaseDate')).strip()), |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
279 parseDate(cvrftracking.findtext(UN('cvrf', 'CurrentReleaseDate')).strip()) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
280 ) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
281 doc.setTracking(tracking) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
282 for cvrfrev in cvrftracking.findall('/'.join([UN('cvrf', 'RevisionHistory'), UN('cvrf', 'Revision')])): |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
283 rev = CVRFRevision( |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
284 parseVersion(cvrfrev.findtext(UN('cvrf', 'Number')).strip()), |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
285 parseDate(cvrfrev.findtext(UN('cvrf', 'Date')).strip()), |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
286 cvrfrev.findtext(UN('cvrf', 'Description')).strip(), |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
287 ) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
288 tracking.addRevision(rev) |
0 | 289 |
5
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
290 xmlgenerator = cvrftracking.find(UN('cvrf', 'Generator')) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
291 if xmlgenerator is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
292 generator = CVRFGenerator() |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
293 xmlengine = xmlgenerator.findtext(UN('cvrf', 'Engine')) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
294 if xmlengine is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
295 generator.setEngine(xmlengine.strip()) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
296 xmldate = xmlgenerator.findtext(UN('cvrf', 'Date')) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
297 if xmldate is not None: |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
298 generator.setDate(parseDate(xmldate.strip())) |
d62264a643fb
Allow parsing of incomplete documents
Benoît Allard <benoit.allard@greenbone.net>
parents:
1
diff
changeset
|
299 tracking.setGenerator(generator) |
0 | 300 |
301 for cvrfnote in cvrfdoc.findall('/'.join([UN('cvrf', 'DocumentNotes'), UN('cvrf', 'Note')])): | |
302 doc.addNote(parseNote(cvrfnote)) | |
303 | |
304 distr = cvrfdoc.findtext(UN('cvrf', 'DocumentDistribution')) | |
305 if distr is not None: | |
306 doc.setDistribution(textwrap.dedent(distr).strip()) | |
307 | |
308 # This is in a quite free format, not sure how to do something with it ... | |
309 xmlaggsev = cvrfdoc.find(UN('cvrf', 'AggregateSeverity')) | |
1
d47e1164740f
Add support for AggregateSeverity
Benoît Allard <benoit.allard@greenbone.net>
parents:
0
diff
changeset
|
310 if xmlaggsev is not None: |
d47e1164740f
Add support for AggregateSeverity
Benoît Allard <benoit.allard@greenbone.net>
parents:
0
diff
changeset
|
311 aggsev = CVRFAggregateSeverity(xmlaggsev.text.strip()) |
d47e1164740f
Add support for AggregateSeverity
Benoît Allard <benoit.allard@greenbone.net>
parents:
0
diff
changeset
|
312 if 'Namespace' in xmlaggsev.attrib: |
d47e1164740f
Add support for AggregateSeverity
Benoît Allard <benoit.allard@greenbone.net>
parents:
0
diff
changeset
|
313 aggsev.setNamespace(xmlaggsev.attrib['Namespace']) |
d47e1164740f
Add support for AggregateSeverity
Benoît Allard <benoit.allard@greenbone.net>
parents:
0
diff
changeset
|
314 doc.setAggregateSeverity(aggsev) |
0 | 315 |
316 for xmlref in cvrfdoc.findall('/'.join([UN('cvrf', 'DocumentReferences'), UN('cvrf', 'Reference')])): | |
317 doc.addReference(parseReference(xmlref)) | |
318 | |
319 for cvrfack in cvrfdoc.findall('/'.join([UN('cvrf', 'Acknowledgments'), UN('cvrf', 'Acknowledgment')])): | |
320 doc.addAcknowledgment(parseAcknowledgment(cvrfack)) | |
321 | |
322 # --- The ProductTree | |
323 | |
324 cvrfptree = cvrfdoc.find(UN('prod', 'ProductTree')) | |
325 if cvrfptree is not None: | |
326 producttree = doc.createProductTree() | |
327 for branch in parseProdBranch(cvrfptree, producttree): | |
328 producttree.addBranch(branch) | |
329 | |
330 for product in cvrfptree.findall(UN('prod', 'FullProductName')): | |
331 producttree.addProduct(parseFullProductName(product, producttree)) | |
332 | |
333 for cvrfrel in cvrfptree.findall(UN('prod', 'Relationship')): | |
334 rel = CVRFRelationship( | |
335 cvrfrel.attrib['ProductReference'], | |
336 cvrfrel.attrib['RelationType'], | |
337 cvrfrel.attrib['RelatesToProductReference'] | |
338 ) | |
339 producttree.addRelationship(rel) | |
340 producttree.addProduct(parseFullProductName(cvrfrel.find(UN('prod', 'FullProductName')), rel)) | |
341 | |
342 for xmlgroup in cvrfptree.findall('/'.join([UN('prod', 'ProductGroups'), UN('prod', 'Group')])): | |
343 group = CVRFGroup(xmlgroup.attrib['GroupID']) | |
344 xmldescr = xmlgroup.findtext(UN('prod', 'Description')) | |
345 if xmldescr is not None: | |
346 group.setDescription(textwrap.dedent(xmldescr).strip()) | |
347 for xmlpid in xmlgroup.findall(UN('prod', 'ProductID')): | |
348 group.addProductID(xmlpid.text.strip()) | |
349 producttree.addGroup(group) | |
350 | |
351 # --- The Vulnerabilities | |
352 | |
353 for cvrfvuln in cvrfdoc.findall(UN('vuln', 'Vulnerability')): | |
354 doc.addVulnerability(parseVulnerability(cvrfvuln)) | |
355 | |
356 return doc | |
357 | |
358 | |
359 if __name__ == "__main__": | |
360 import sys | |
361 with open(sys.argv[1], 'rt') as f: | |
362 cvrf = parse(f) | |
363 cvrf.validate() | |
364 print(cvrf) | |
365 print(cvrf.getHighestCVSS()._vector) | |
366 print(cvrf.getProductList()) | |
367 print(cvrf._producttree._branches) | |
368 # print(cvrf._producttree._branches[0]._childs) |