summaryrefslogtreecommitdiffstats
path: root/scripts/cve-json-to-text.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/cve-json-to-text.py')
-rwxr-xr-xscripts/cve-json-to-text.py146
1 files changed, 146 insertions, 0 deletions
diff --git a/scripts/cve-json-to-text.py b/scripts/cve-json-to-text.py
new file mode 100755
index 0000000000..8d309b37e5
--- /dev/null
+++ b/scripts/cve-json-to-text.py
@@ -0,0 +1,146 @@
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
9import sys
10import getopt
11
12infile = "in.json"
13outfile = "out.txt"
14
15
16def 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
26def 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
37def 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
58def 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
79def 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
139def main(argv):
140 parse_args(argv)
141 data = load_json(infile)
142 process_data(outfile, data)
143
144
145if __name__ == "__main__":
146 main(sys.argv[1:])