blob: 87a5669987cca535a49c3ce7227c44d39f5f8917 [file] [log] [blame]
#!/bin/env python3
# SPDX-FileCopyrightText: OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
# CVE results conversion script: JSON format to text
# Derived from cve-report.py from Oniro (MIT, by Huawei Inc)
import sys
import getopt
infile = "in.json"
outfile = "out.txt"
def show_syntax_and_exit(code):
"""
Show the program syntax and exit with an errror
Arguments:
code: the error code to return
"""
print("Syntax: %s [-h] [-i inputJSONfile][-o outputfile]" % sys.argv[0])
sys.exit(code)
def exit_error(code, message):
"""
Show the error message and exit with an errror
Arguments:
code: the error code to return
message: the message to show
"""
print("Error: %s" % message)
sys.exit(code)
def parse_args(argv):
"""
Parse the program arguments, put options in global variables
Arguments:
argv: program arguments
"""
global infile, outfile
try:
opts, args = getopt.getopt(
argv, "hi:o:", ["help", "input", "output"]
)
except getopt.GetoptError:
show_syntax_and_exit(1)
for opt, arg in opts:
if opt in ("-h", "--help"):
show_syntax_and_exit(0)
elif opt in ("-a", "--all"):
show_all = True
show_unknown = True
elif opt in ("-i", "--input"):
infile = arg
def load_json(filename):
"""
Load the JSON file, return the resulting dictionary
Arguments:
filename: the file to open
Returns:
Parsed file as a dictionary
"""
import json
out = {}
try:
with open(filename, "r") as f:
out = json.load(f)
except FileNotFoundError:
exit_error(1, "Input file (%s) not found" % (filename))
except json.decoder.JSONDecodeError as error:
exit_error(1, "Malformed JSON file: %s" % str(error))
return out
def process_data(filename, data):
"""
Write the resulting CSV with one line for each package
Arguments:
filename: the file to write to
data: dictionary from parsing the JSON file
Returns:
None
"""
if not "version" in data or data["version"] != "1":
exit_error(1, "Unrecognized format version number")
if not "package" in data:
exit_error(1, "Mandatory 'package' key not found")
lines = ""
total_issue_count = 0
for package in data["package"]:
package_info = ""
keys_in_package = {"name", "layer", "version", "issue"}
if keys_in_package - package.keys():
exit_error(
1,
"Missing a mandatory key in package: %s"
% (keys_in_package - package.keys()),
)
package_info += "LAYER: %s\n" % package["layer"]
package_info += "PACKAGE NAME: %s\n" % package["name"]
package_info += "PACKAGE VERSION: %s\n" % package["version"]
for issue in package["issue"]:
keys_in_issue = {"id", "status", "detail"}
if keys_in_issue - issue.keys():
print("Warning: Missing keys %s in 'issue' for the package '%s'"
% (keys_in_issue - issue.keys(), package["name"]))
lines += package_info
lines += "CVE: %s\n" % issue["id"]
lines += "CVE STATUS: %s\n" % issue["status"]
lines += "CVE DETAIL: %s\n" % issue["detail"]
if "description" in issue:
lines += "CVE DESCRIPTION: %s\n" % issue["description"]
if "summary" in issue:
lines += "CVE SUMMARY: %s\n" % issue["summary"]
if "scorev2" in issue:
lines += "CVSS v2 BASE SCORE: %s\n" % issue["scorev2"]
if "scorev3" in issue:
lines += "CVSS v3 BASE SCORE: %s\n" % issue["scorev3"]
if "scorev4" in issue:
lines += "CVSS v4 BASE SCORE: %s\n" % issue["scorev4"]
if "vector" in issue:
lines += "VECTOR: %s\n" % issue["vector"]
if "vectorString" in issue:
lines += "VECTORSTRING: %s\n" % issue["vectorString"]
lines += "MORE INFORMATION: https://nvd.nist.gov/vuln/detail/%s\n" % issue["id"]
lines += "\n"
with open(filename, "w") as f:
f.write(lines)
def main(argv):
parse_args(argv)
data = load_json(infile)
process_data(outfile, data)
if __name__ == "__main__":
main(sys.argv[1:])