#!/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:])