diff options
Diffstat (limited to 'scripts/cve-json-to-text.py')
| -rwxr-xr-x | scripts/cve-json-to-text.py | 146 |
1 files changed, 0 insertions, 146 deletions
diff --git a/scripts/cve-json-to-text.py b/scripts/cve-json-to-text.py deleted file mode 100755 index 8d309b37e5..0000000000 --- a/scripts/cve-json-to-text.py +++ /dev/null | |||
| @@ -1,146 +0,0 @@ | |||
| 1 | #!/bin/env python3 | ||
| 2 | # SPDX-FileCopyrightText: OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | |||
| 6 | # CVE results conversion script: JSON format to text | ||
| 7 | # Derived from cve-report.py from Oniro (MIT, by Huawei Inc) | ||
| 8 | |||
| 9 | import sys | ||
| 10 | import getopt | ||
| 11 | |||
| 12 | infile = "in.json" | ||
| 13 | outfile = "out.txt" | ||
| 14 | |||
| 15 | |||
| 16 | def show_syntax_and_exit(code): | ||
| 17 | """ | ||
| 18 | Show the program syntax and exit with an errror | ||
| 19 | Arguments: | ||
| 20 | code: the error code to return | ||
| 21 | """ | ||
| 22 | print("Syntax: %s [-h] [-i inputJSONfile][-o outputfile]" % sys.argv[0]) | ||
| 23 | sys.exit(code) | ||
| 24 | |||
| 25 | |||
| 26 | def exit_error(code, message): | ||
| 27 | """ | ||
| 28 | Show the error message and exit with an errror | ||
| 29 | Arguments: | ||
| 30 | code: the error code to return | ||
| 31 | message: the message to show | ||
| 32 | """ | ||
| 33 | print("Error: %s" % message) | ||
| 34 | sys.exit(code) | ||
| 35 | |||
| 36 | |||
| 37 | def parse_args(argv): | ||
| 38 | """ | ||
| 39 | Parse the program arguments, put options in global variables | ||
| 40 | Arguments: | ||
| 41 | argv: program arguments | ||
| 42 | """ | ||
| 43 | global infile, outfile | ||
| 44 | try: | ||
| 45 | opts, args = getopt.getopt( | ||
| 46 | argv, "hi:o:", ["help", "input", "output"] | ||
| 47 | ) | ||
| 48 | except getopt.GetoptError: | ||
| 49 | show_syntax_and_exit(1) | ||
| 50 | for opt, arg in opts: | ||
| 51 | if opt in ("-h"): | ||
| 52 | show_syntax_and_exit(0) | ||
| 53 | elif opt in ("-i"): | ||
| 54 | infile = arg | ||
| 55 | elif opt in ("-o"): | ||
| 56 | outfile = arg | ||
| 57 | |||
| 58 | def load_json(filename): | ||
| 59 | """ | ||
| 60 | Load the JSON file, return the resulting dictionary | ||
| 61 | Arguments: | ||
| 62 | filename: the file to open | ||
| 63 | Returns: | ||
| 64 | Parsed file as a dictionary | ||
| 65 | """ | ||
| 66 | import json | ||
| 67 | |||
| 68 | out = {} | ||
| 69 | try: | ||
| 70 | with open(filename, "r") as f: | ||
| 71 | out = json.load(f) | ||
| 72 | except FileNotFoundError: | ||
| 73 | exit_error(1, "Input file (%s) not found" % (filename)) | ||
| 74 | except json.decoder.JSONDecodeError as error: | ||
| 75 | exit_error(1, "Malformed JSON file: %s" % str(error)) | ||
| 76 | return out | ||
| 77 | |||
| 78 | |||
| 79 | def process_data(filename, data): | ||
| 80 | """ | ||
| 81 | Write the resulting CSV with one line for each package | ||
| 82 | Arguments: | ||
| 83 | filename: the file to write to | ||
| 84 | data: dictionary from parsing the JSON file | ||
| 85 | Returns: | ||
| 86 | None | ||
| 87 | """ | ||
| 88 | if not "version" in data or data["version"] != "1": | ||
| 89 | exit_error(1, "Unrecognized format version number") | ||
| 90 | if not "package" in data: | ||
| 91 | exit_error(1, "Mandatory 'package' key not found") | ||
| 92 | |||
| 93 | lines = "" | ||
| 94 | total_issue_count = 0 | ||
| 95 | for package in data["package"]: | ||
| 96 | package_info = "" | ||
| 97 | keys_in_package = {"name", "layer", "version", "issue"} | ||
| 98 | if keys_in_package - package.keys(): | ||
| 99 | exit_error( | ||
| 100 | 1, | ||
| 101 | "Missing a mandatory key in package: %s" | ||
| 102 | % (keys_in_package - package.keys()), | ||
| 103 | ) | ||
| 104 | |||
| 105 | package_info += "LAYER: %s\n" % package["layer"] | ||
| 106 | package_info += "PACKAGE NAME: %s\n" % package["name"] | ||
| 107 | package_info += "PACKAGE VERSION: %s\n" % package["version"] | ||
| 108 | |||
| 109 | for issue in package["issue"]: | ||
| 110 | keys_in_issue = {"id", "status", "detail"} | ||
| 111 | if keys_in_issue - issue.keys(): | ||
| 112 | print("Warning: Missing keys %s in 'issue' for the package '%s'" | ||
| 113 | % (keys_in_issue - issue.keys(), package["name"])) | ||
| 114 | |||
| 115 | lines += package_info | ||
| 116 | lines += "CVE: %s\n" % issue["id"] | ||
| 117 | lines += "CVE STATUS: %s\n" % issue["status"] | ||
| 118 | lines += "CVE DETAIL: %s\n" % issue["detail"] | ||
| 119 | if "description" in issue: | ||
| 120 | lines += "CVE DESCRIPTION: %s\n" % issue["description"] | ||
| 121 | if "summary" in issue: | ||
| 122 | lines += "CVE SUMMARY: %s\n" % issue["summary"] | ||
| 123 | if "scorev2" in issue: | ||
| 124 | lines += "CVSS v2 BASE SCORE: %s\n" % issue["scorev2"] | ||
| 125 | if "scorev3" in issue: | ||
| 126 | lines += "CVSS v3 BASE SCORE: %s\n" % issue["scorev3"] | ||
| 127 | if "scorev4" in issue: | ||
| 128 | lines += "CVSS v4 BASE SCORE: %s\n" % issue["scorev4"] | ||
| 129 | if "vector" in issue: | ||
| 130 | lines += "VECTOR: %s\n" % issue["vector"] | ||
| 131 | if "vectorString" in issue: | ||
| 132 | lines += "VECTORSTRING: %s\n" % issue["vectorString"] | ||
| 133 | lines += "MORE INFORMATION: https://nvd.nist.gov/vuln/detail/%s\n" % issue["id"] | ||
| 134 | lines += "\n" | ||
| 135 | |||
| 136 | with open(filename, "w") as f: | ||
| 137 | f.write(lines) | ||
| 138 | |||
| 139 | def main(argv): | ||
| 140 | parse_args(argv) | ||
| 141 | data = load_json(infile) | ||
| 142 | process_data(outfile, data) | ||
| 143 | |||
| 144 | |||
| 145 | if __name__ == "__main__": | ||
| 146 | main(sys.argv[1:]) | ||
