2020# VulnerableCode is a free software code from nexB Inc. and others.
2121# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2222
23-
24- import json
25-
2623from packageurl import PackageURL
2724import requests
2825
@@ -38,40 +35,56 @@ class RedhatDataSource(DataSource):
3835 CONFIG_CLASS = DataSourceConfiguration
3936
4037 def __enter__ (self ):
41- self .redhat_response = fetch ()
4238
43- def updated_advisories (self ):
44- processed_advisories = []
45- for advisory_data in self .redhat_response :
46- processed_advisories .append (to_advisory (advisory_data ))
39+ self .redhat_cves = fetch ()
4740
41+ def updated_advisories (self ):
42+ processed_advisories = list (map (to_advisory , self .redhat_cves ))
4843 return self .batch_advisories (processed_advisories )
4944
5045
5146def fetch ():
52-
53- response = []
47+ """
48+ Return a list of CVE data mappings fetched from the RedHat API.
49+ See:
50+ https://access.redhat.com/documentation/en-us/red_hat_security_data_api/1.0/html/red_hat_security_data_api/index
51+ """
52+ cves = []
5453 page_no = 1
55- url = "https://access.redhat.com/hydra/rest/securitydata/cve.json?page={}"
54+ url_template = "https://access.redhat.com/hydra/rest/securitydata/cve.json?per_page=10000& page={}" # nopep8
5655
56+ cve_data = None
5757 while True :
58- resp_json = requests .get (url .format (page_no )).json ()
59- page_no += 1
60- if not resp_json :
58+ current_url = url_template .format (page_no )
59+ try :
60+ print (f"Fetching: { current_url } " )
61+ response = requests .get (current_url )
62+ if response .status_code != requests .codes .ok :
63+ # TODO: log me
64+ print (f"Failed to fetch results from { current_url } " )
65+ break
66+ cve_data = response .json ()
67+ except Exception as e :
68+ # TODO: log me
69+ msg = f"Failed to fetch results from { current_url } :\n { e } "
70+ print (msg )
6171 break
6272
63- for advisory in resp_json :
64- response .append (advisory )
73+ if not cve_data :
74+ break
75+ cves .extend (cve_data )
76+ page_no += 1
6577
66- return response
78+ return cves
6779
6880
6981def to_advisory (advisory_data ):
7082 affected_purls = []
7183 if advisory_data .get ("affected_packages" ):
7284 for rpm in advisory_data ["affected_packages" ]:
73- if rpm_to_purl (rpm ):
74- affected_purls .append (rpm_to_purl (rpm ))
85+ purl = rpm_to_purl (rpm )
86+ if purl :
87+ affected_purls .append (purl )
7588
7689 references = []
7790 bugzilla = advisory_data .get ("bugzilla" )
@@ -135,16 +148,17 @@ def to_advisory(advisory_data):
135148 )
136149
137150 references .append (Reference (severities = redhat_scores , url = advisory_data ["resource_url" ]))
138-
139151 return Advisory (
140- summary = advisory_data ["bugzilla_description" ],
141152 vulnerability_id = advisory_data ["CVE" ],
153+ summary = advisory_data ["bugzilla_description" ],
142154 impacted_package_urls = affected_purls ,
143155 vuln_references = references ,
144156 )
145157
146158
147159def rpm_to_purl (rpm_string ):
160+ # FIXME: there is code in scancode to handle RPM conversion AND this should
161+ # be all be part of the packageurl library
148162
149163 # Red Hat uses `-:0` instead of just `-` to separate
150164 # package name and version
@@ -155,4 +169,4 @@ def rpm_to_purl(rpm_string):
155169 name , version = components
156170
157171 if version [0 ].isdigit ():
158- return PackageURL (name = name , type = "rpm" , version = version , namespace = "redhat" )
172+ return PackageURL (namespace = "redhat" , name = name , type = "rpm" , version = version )
0 commit comments