Merge ~ebarretto/ubuntu-cve-tracker:oval-bugs into ubuntu-cve-tracker:master
- Git
- lp:~ebarretto/ubuntu-cve-tracker
- oval-bugs
- Merge into master
Proposed by
Eduardo Barretto
Status: | Merged |
---|---|
Merge reported by: | Eduardo Barretto |
Merged at revision: | 11ea9be3dc481fe183ffb6bf66401461cb8fb189 |
Proposed branch: | ~ebarretto/ubuntu-cve-tracker:oval-bugs |
Merge into: | ubuntu-cve-tracker:master |
Diff against target: |
933 lines (+134/-351) 7 files modified
scripts/cve_lib.py (+2/-0) scripts/generate-oval (+74/-291) scripts/oval_lib.py (+42/-44) test/test_oval_lib_end_to_end.py (+4/-4) test/test_oval_lib_functional.py (+6/-6) test/test_oval_lib_unit.py (+3/-3) test/test_utils.py (+3/-3) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Fernandez Gonzalez | Approve | ||
Ubuntu Security Team | Pending | ||
Review via email: mp+461249@code.launchpad.net |
Commit message
Description of the change
Some clean-up on generate-oval:
- removed unused variables, fuctions and imports
- removed --cve-prefix-dir
- improved helper descriptions
- added --type flag, removed --usn-oval and --pkg-oval
- rework calls to OCI OVAL generation
- rework tests to address new changes
PS: There's a few commits that launchpad is not showing, you might want to look directly at the branch.
To post a comment you must log in.
- 11ea9be... by Eduardo Barretto
-
generate-oval: make oval-releases use nargs instead of appending
This allow single calls with --oval-releases bionic xenial
instead of --oval-releases bionic --oval-releases xenial
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/scripts/cve_lib.py b/scripts/cve_lib.py | |||
2 | index 416d5f7..090cdea 100755 | |||
3 | --- a/scripts/cve_lib.py | |||
4 | +++ b/scripts/cve_lib.py | |||
5 | @@ -492,6 +492,7 @@ subprojects = { | |||
6 | 492 | }, | 492 | }, |
7 | 493 | "ubuntu/trusty": { | 493 | "ubuntu/trusty": { |
8 | 494 | "eol": True, | 494 | "eol": True, |
9 | 495 | "oval": True, | ||
10 | 495 | "components": ["main", "restricted", "universe", "multiverse"], | 496 | "components": ["main", "restricted", "universe", "multiverse"], |
11 | 496 | "name": "Ubuntu 14.04 LTS", | 497 | "name": "Ubuntu 14.04 LTS", |
12 | 497 | "version": 14.04, | 498 | "version": 14.04, |
13 | @@ -532,6 +533,7 @@ subprojects = { | |||
14 | 532 | }, | 533 | }, |
15 | 533 | "ubuntu/xenial": { | 534 | "ubuntu/xenial": { |
16 | 534 | "eol": True, | 535 | "eol": True, |
17 | 536 | "oval": True, | ||
18 | 535 | "components": ["main", "restricted", "universe", "multiverse"], | 537 | "components": ["main", "restricted", "universe", "multiverse"], |
19 | 536 | "name": "Ubuntu 16.04 LTS", | 538 | "name": "Ubuntu 16.04 LTS", |
20 | 537 | "version": 16.04, | 539 | "version": 16.04, |
21 | diff --git a/scripts/generate-oval b/scripts/generate-oval | |||
22 | index 920bba6..c555304 100755 | |||
23 | --- a/scripts/generate-oval | |||
24 | +++ b/scripts/generate-oval | |||
25 | @@ -32,31 +32,11 @@ import os | |||
26 | 32 | import re | 32 | import re |
27 | 33 | import sys | 33 | import sys |
28 | 34 | 34 | ||
32 | 35 | import apt_pkg | 35 | from cve_lib import (product_series, PRODUCT_UBUNTU, all_releases, eol_releases, devel_release, release_parent, release_name, needs_oval) |
30 | 36 | from cve_lib import (kernel_srcs, product_series, load_cve, PRODUCT_UBUNTU, all_releases, eol_releases, devel_release, release_parent, release_name, release_progenitor, needs_oval) | ||
31 | 37 | from kernel_lib import meta_kernels | ||
33 | 38 | import oval_lib | 36 | import oval_lib |
34 | 39 | 37 | ||
35 | 40 | # cope with apt_pkg api changes. | ||
36 | 41 | if 'init_system' in dir(apt_pkg): | ||
37 | 42 | apt_pkg.init_system() | ||
38 | 43 | else: | ||
39 | 44 | apt_pkg.InitSystem() | ||
40 | 45 | |||
41 | 46 | supported_releases = [] | ||
42 | 47 | for r in set(all_releases).difference(set(eol_releases)).difference(set([devel_release])): | ||
43 | 48 | if needs_oval(r): | ||
44 | 49 | supported_releases.append(r) | ||
45 | 50 | parent = release_parent(r) | ||
46 | 51 | if parent and parent not in supported_releases: | ||
47 | 52 | supported_releases.append(parent) | ||
48 | 53 | |||
49 | 54 | default_cves_to_process = ['active/CVE-*', 'retired/CVE-*'] | ||
50 | 55 | |||
51 | 56 | debug_level = 0 | 38 | debug_level = 0 |
52 | 57 | 39 | ||
53 | 58 | package_cache = None | ||
54 | 59 | |||
55 | 60 | def main(): | 40 | def main(): |
56 | 61 | """ parse command line options and iterate through files to be processed | 41 | """ parse command line options and iterate through files to be processed |
57 | 62 | """ | 42 | """ |
58 | @@ -64,9 +44,10 @@ def main(): | |||
59 | 64 | global supported_releases | 44 | global supported_releases |
60 | 65 | 45 | ||
61 | 66 | # parse command line options | 46 | # parse command line options |
65 | 67 | parser = argparse.ArgumentParser(description='Generate CVE OVAL from ' | 47 | parser = argparse.ArgumentParser(description='Generate OVAL for CVE, PKG or USNs.') |
66 | 68 | 'CVE metadata files.') | 48 | parser.add_argument('--type', required=True, choices=['cve', 'pkg', 'usn'], |
67 | 69 | parser.add_argument('pathname', nargs='*', | 49 | help='OVAL format') |
68 | 50 | parser.add_argument('--cves', nargs='*', default=['active/CVE-*', 'retired/CVE-*'], | ||
69 | 70 | help='pathname patterns (globs) specifying CVE ' | 51 | help='pathname patterns (globs) specifying CVE ' |
70 | 71 | 'metadata files to be converted into OVAL ' | 52 | 'metadata files to be converted into OVAL ' |
71 | 72 | '(default: "./active/CVE-*" "./retired/CVE-*")') | 53 | '(default: "./active/CVE-*" "./retired/CVE-*")') |
72 | @@ -78,255 +59,76 @@ def main(): | |||
73 | 78 | help='output directory for OCI manifest OVAL files (default is to use the same directory as --output-dir)') | 59 | help='output directory for OCI manifest OVAL files (default is to use the same directory as --output-dir)') |
74 | 79 | parser.add_argument('--oci-prefix', nargs='?', default='oci.', | 60 | parser.add_argument('--oci-prefix', nargs='?', default='oci.', |
75 | 80 | help='Prefix to use for OCI manifest OVAL files names (required if oci-output-dir is the same as output-dir)') | 61 | help='Prefix to use for OCI manifest OVAL files names (required if oci-output-dir is the same as output-dir)') |
76 | 81 | parser.add_argument('--cve-prefix-dir', nargs='?', default='./', | ||
77 | 82 | help='location of CVE metadata files to process ' | ||
78 | 83 | '(default is ./)') | ||
79 | 84 | parser.add_argument('--no-progress', action='store_true', | 62 | parser.add_argument('--no-progress', action='store_true', |
80 | 85 | help='do not show progress meter') | 63 | help='do not show progress meter') |
81 | 86 | parser.add_argument('--pkg-cache-dir', action='store', default='./', | 64 | parser.add_argument('--pkg-cache-dir', action='store', default='./', |
82 | 87 | help='cache location for binary packages') | 65 | help='cache location for binary packages') |
83 | 88 | parser.add_argument('-d', '--debug', action='count', default=0, | 66 | parser.add_argument('-d', '--debug', action='count', default=0, |
84 | 89 | help="report debugging information") | 67 | help="report debugging information") |
85 | 90 | parser.add_argument('--usn-oval', action='store_true', | ||
86 | 91 | help='generates oval from the USN database') | ||
87 | 92 | parser.add_argument('--pkg-oval', action='store_true', | ||
88 | 93 | help='generates oval from the Package database') | ||
89 | 94 | parser.add_argument('--usn-db-dir', default='./', type=str, | 68 | parser.add_argument('--usn-db-dir', default='./', type=str, |
90 | 95 | help='location of USN database.json to process ' | 69 | help='location of USN database.json to process ' |
91 | 96 | '(default is ./)') | 70 | '(default is ./)') |
92 | 97 | parser.add_argument('--usn-number', default=None, type=str, | 71 | parser.add_argument('--usn-number', default=None, type=str, |
93 | 98 | help='if passed specifics a USN for the oval_usn generator') | 72 | help='if passed specifics a USN for the oval_usn generator') |
96 | 99 | parser.add_argument('--oval-releases', default=None, action='append', | 73 | parser.add_argument('--oval-releases', default=None, nargs='+', |
97 | 100 | help='specifies releases to generate the oval') | 74 | help='only generate OVAL for specific releases') |
98 | 101 | parser.add_argument('--packages', nargs='+', action='store', default=None, | 75 | parser.add_argument('--packages', nargs='+', action='store', default=None, |
101 | 102 | help='generates oval for specific packages. Only for ' | 76 | help='generates OVAL for specific packages') |
100 | 103 | 'CVE OVAL') | ||
102 | 104 | parser.add_argument('--fixed-only', action='store_true', | 77 | parser.add_argument('--fixed-only', action='store_true', |
107 | 105 | help='only generate pkg oval for fixed CVEs') | 78 | help='only generate OVAL for fixed CVEs') |
108 | 106 | parser.add_argument('--expand', action='store_true', | 79 | parser.add_argument('--expand', action='store_true', default=False, |
109 | 107 | help='avoids combining all the oval data into one ' | 80 | help='avoids combining all the OVAL data into one ' |
110 | 108 | 'file and expands the output oval files into different ' | 81 | 'file and expands the output OVAL files into different ' |
111 | 109 | 'releases, such as esm-apps, esm-infra, and ubuntu') | 82 | 'releases, such as esm-apps, esm-infra, and ubuntu') |
112 | 110 | 83 | ||
113 | 111 | args = parser.parse_args() | 84 | args = parser.parse_args() |
114 | 112 | pathnames = args.pathname or default_cves_to_process | ||
115 | 113 | debug_level = args.debug | 85 | debug_level = args.debug |
116 | 114 | 86 | ||
146 | 115 | # debugging; caution, can expose credentials | 87 | if args.output_dir and not os.path.isdir(args.output_dir): |
147 | 116 | if debug_level >= 2: | 88 | raise FileNotFoundError("Could not find '%s'" % args.output_dir) |
119 | 117 | import httplib2 | ||
120 | 118 | httplib2.debuglevel = 1 | ||
121 | 119 | |||
122 | 120 | # create oval generators for each supported release | ||
123 | 121 | outdir = './' | ||
124 | 122 | if args.output_dir: | ||
125 | 123 | outdir = args.output_dir | ||
126 | 124 | if not os.path.isdir(outdir): | ||
127 | 125 | raise FileNotFoundError("Could not find '%s'" % outdir) | ||
128 | 126 | if args.oci: | ||
129 | 127 | if args.oci_output_dir: | ||
130 | 128 | ocioutdir = args.oci_output_dir | ||
131 | 129 | else: | ||
132 | 130 | ocioutdir = args.output_dir | ||
133 | 131 | if not os.path.isdir(ocioutdir): | ||
134 | 132 | raise FileNotFoundError("Could not find '%s'" % ocioutdir) | ||
135 | 133 | ociprefix = args.oci_prefix | ||
136 | 134 | if outdir == ocioutdir and len(ociprefix) < 1: | ||
137 | 135 | raise ValueError("oci-prefix must be set when output-dir and oci-output-dir are the same") | ||
138 | 136 | |||
139 | 137 | if args.usn_oval: | ||
140 | 138 | if args.oci: | ||
141 | 139 | generate_oval_usn(args.output_dir, args.usn_number, args.oval_releases, | ||
142 | 140 | args.cve_prefix_dir, args.usn_db_dir, args.no_progress, ociprefix, ocioutdir) | ||
143 | 141 | else: | ||
144 | 142 | generate_oval_usn(args.output_dir, args.usn_number, args.oval_releases, | ||
145 | 143 | args.cve_prefix_dir, args.usn_db_dir, args.no_progress,) | ||
148 | 144 | 89 | ||
150 | 145 | return | 90 | if args.oci_prefix: |
151 | 91 | if not args.oci_output_dir: | ||
152 | 92 | args.oci_output_dir = args.output_dir | ||
153 | 93 | elif args.output_dir == args.oci_output_dir and len(args.oci_prefix) < 1: | ||
154 | 94 | raise ValueError("oci-prefix must be set when output-dir and oci-output-dir are the same") | ||
155 | 146 | 95 | ||
160 | 147 | # if --oval-release, we still need to load parents cache | 96 | releases = [] |
157 | 148 | # so we can generate a complete oval for those releases that | ||
158 | 149 | # have a parent | ||
159 | 150 | releases = supported_releases | ||
161 | 151 | if args.oval_releases: | 97 | if args.oval_releases: |
162 | 152 | releases = args.oval_releases | 98 | releases = args.oval_releases |
163 | 153 | for release in releases: | 99 | for release in releases: |
165 | 154 | if release not in supported_releases: | 100 | if not needs_oval(release): |
166 | 155 | error(f"unknown oval release {release}") | 101 | error(f"unknown oval release {release}") |
167 | 102 | else: | ||
168 | 103 | releases = [] | ||
169 | 104 | for r in set(all_releases).difference(set(eol_releases)).difference(set([devel_release])): | ||
170 | 105 | if needs_oval(r): | ||
171 | 106 | releases.append(r) | ||
172 | 107 | |||
173 | 108 | # for each release we need to get its parent to also | ||
174 | 109 | # load their cache data in order to generate a complete | ||
175 | 110 | # oval for such release | ||
176 | 111 | parent_releases = set() | ||
177 | 112 | for release in releases: | ||
178 | 113 | while(release_parent(release)): | ||
179 | 114 | release = release_parent(release) | ||
180 | 115 | parent_releases.add(release) | ||
181 | 156 | 116 | ||
195 | 157 | expand = args.expand | 117 | releases = set(releases + list(parent_releases)) |
183 | 158 | |||
184 | 159 | cache = {} | ||
185 | 160 | for release in supported_releases: | ||
186 | 161 | cve_cache = {} | ||
187 | 162 | cache.update({release: get_package_cache(args.pkg_cache_dir, release)}) | ||
188 | 163 | |||
189 | 164 | if args.pkg_oval: | ||
190 | 165 | if args.oci: | ||
191 | 166 | generate_oval_package(releases, outdir, args.cve_prefix_dir, cache, cve_cache, args.oci, args.no_progress, args.packages, pathnames, args.fixed_only, ocioutdir, expand) | ||
192 | 167 | else: | ||
193 | 168 | generate_oval_package(releases, outdir, args.cve_prefix_dir, cache, cve_cache, args.oci, args.no_progress, args.packages, pathnames, args.fixed_only, expand) | ||
194 | 169 | return | ||
196 | 170 | 118 | ||
199 | 171 | if args.oci: | 119 | if args.type == 'usn': |
200 | 172 | generate_oval_cve(releases, outdir, args.cve_prefix_dir, cache, cve_cache, args.oci, args.no_progress, args.packages, pathnames, args.fixed_only, ocioutdir, expand) | 120 | generate_oval_usn(args.output_dir, args.usn_number, releases, |
201 | 121 | args.cves, args.usn_db_dir, args.no_progress, args.oci_prefix, args.oci_output_dir) | ||
202 | 173 | else: | 122 | else: |
359 | 174 | generate_oval_cve(releases, outdir, args.cve_prefix_dir, cache, cve_cache, args.oci, args.no_progress, args.packages, pathnames, args.fixed_only, expand) | 123 | cache = {} |
360 | 175 | return | 124 | for release in releases: |
361 | 176 | 125 | cve_cache = {} | |
362 | 177 | 126 | cache.update({release: get_package_cache(args.pkg_cache_dir, release)}) | |
363 | 178 | # given a status generated by parse_package_status(), duplicate it for a | 127 | |
364 | 179 | # different source package, computing binary packages for the new source | 128 | if args.type == 'pkg': |
365 | 180 | # package | 129 | generate_oval_package(releases, args.output_dir, args.cves, cache, cve_cache, args.oci, args.no_progress, args.packages, args.fixed_only, args.oci_output_dir, args.expand) |
366 | 181 | def duplicate_package_status(release, package, original_status, cache, override_version=None): | 130 | elif args.type == 'cve': |
367 | 182 | copied_status = {} | 131 | generate_oval_cve(releases, args.output_dir, args.cves, cache, cve_cache, args.oci, args.no_progress, args.packages, args.fixed_only, args.oci_output_dir, args.expand) |
212 | 183 | copied_status['status'] = original_status['status'] | ||
213 | 184 | copied_status['note'] = original_status['note'] | ||
214 | 185 | if override_version: | ||
215 | 186 | copied_status['fix-version'] = override_version | ||
216 | 187 | elif 'fix-version' in original_status: | ||
217 | 188 | copied_status['fix-version'] = original_status['fix-version'] | ||
218 | 189 | |||
219 | 190 | if 'bin-pkgs' in original_status: | ||
220 | 191 | copied_status['bin-pkgs'] = original_status['bin-pkgs'] | ||
221 | 192 | |||
222 | 193 | return copied_status | ||
223 | 194 | |||
224 | 195 | |||
225 | 196 | # returns True if we should ignore this source package; primarily used | ||
226 | 197 | # for -edge kernels | ||
227 | 198 | def ignore_source_package(source): | ||
228 | 199 | if re.match('linux-.*-edge$', source): | ||
229 | 200 | return True | ||
230 | 201 | if re.match('linux-riscv.*$', source): | ||
231 | 202 | # linux-riscv.* currently causes a lot of false positives, skip | ||
232 | 203 | # it altogether while we don't land a better fix | ||
233 | 204 | return True | ||
234 | 205 | return False | ||
235 | 206 | |||
236 | 207 | |||
237 | 208 | def parse_cve_file(filepath, cache, pkg_filter=None, expand=False): | ||
238 | 209 | """ parse CVE data file into a dictionary using cve_lib """ | ||
239 | 210 | |||
240 | 211 | cve_header_data = { | ||
241 | 212 | 'Candidate': '', | ||
242 | 213 | 'CRD': '', | ||
243 | 214 | 'PublicDate': '', | ||
244 | 215 | 'PublicDateAtUSN': '', | ||
245 | 216 | 'References': [get_cve_url(filepath)], | ||
246 | 217 | 'Description': '', | ||
247 | 218 | 'Ubuntu-Description': '', | ||
248 | 219 | 'Notes': '', | ||
249 | 220 | 'Mitigation': '', | ||
250 | 221 | 'Bugs': [], | ||
251 | 222 | 'Priority': '', | ||
252 | 223 | 'Discovered-by': '', | ||
253 | 224 | 'Assigned-to': '', | ||
254 | 225 | 'CVSS': '', | ||
255 | 226 | 'Unknown-Fields': [], | ||
256 | 227 | 'Source-note': filepath | ||
257 | 228 | } | ||
258 | 229 | data = load_cve(filepath) | ||
259 | 230 | # first try a naive translation of fields | ||
260 | 231 | for f in cve_header_data: | ||
261 | 232 | try: | ||
262 | 233 | cve_header_data[f] = data[f] | ||
263 | 234 | except KeyError: | ||
264 | 235 | pass | ||
265 | 236 | |||
266 | 237 | # then handle any particular fields which are expected to have a | ||
267 | 238 | # different format | ||
268 | 239 | cve_header_data['Description'] = cve_header_data['Description'].strip().replace('\n', ' ') | ||
269 | 240 | cve_header_data['Ubuntu-Description'] = cve_header_data['Ubuntu-Description'].strip().replace('\n', ' ') | ||
270 | 241 | cve_header_data['References'] = [ref.strip() for ref in cve_header_data['References'].split('\n') if len(ref.strip()) > 0] | ||
271 | 242 | cve_header_data['References'].insert(0, get_cve_url(filepath)) | ||
272 | 243 | cve_header_data['Bugs'] = [bug.strip() for bug in cve_header_data['Bugs'].split('\n') if len(bug.strip()) > 0] | ||
273 | 244 | cve_header_data['Notes'] = ' '.join(user + '> ' + note.replace('\n', ' ') for user, note in cve_header_data['Notes']) | ||
274 | 245 | cve_header_data['Priority'] = cve_header_data['Priority'][0] | ||
275 | 246 | packages = {} | ||
276 | 247 | for pkg in data['pkgs']: | ||
277 | 248 | if ignore_source_package(pkg): | ||
278 | 249 | continue | ||
279 | 250 | if pkg_filter: | ||
280 | 251 | if pkg not in pkg_filter: | ||
281 | 252 | continue | ||
282 | 253 | |||
283 | 254 | packages[pkg] = {'Releases': {}, | ||
284 | 255 | 'Priority': '', | ||
285 | 256 | 'Tags': []} | ||
286 | 257 | for rel in data['pkgs'][pkg]: | ||
287 | 258 | if rel in ['upstream', 'devel']: | ||
288 | 259 | continue | ||
289 | 260 | if rel not in supported_releases: | ||
290 | 261 | continue | ||
291 | 262 | state, details = data['pkgs'][pkg][rel] | ||
292 | 263 | packages[pkg]['Releases'][rel] = oval_lib.CVEPkgRelEntry.parse_package_status(rel, pkg, state, details, filepath, cache, oval_lib.find_release_codename(rel), expand) | ||
293 | 264 | |||
294 | 265 | # add supplemental packages; usually kernels only need this special case. | ||
295 | 266 | for package in [name for name in packages if name in kernel_srcs]: | ||
296 | 267 | for release in [ | ||
297 | 268 | rel for rel in packages[package]['Releases'] | ||
298 | 269 | if packages[package]['Releases'][rel]['status'] != 'not-applicable' | ||
299 | 270 | ]: | ||
300 | 271 | # add signed package | ||
301 | 272 | # handle signed package of subprojects without needing to have them in kernel_lib | ||
302 | 273 | progenitor = release_progenitor(release) | ||
303 | 274 | if progenitor: | ||
304 | 275 | signed_pkg = meta_kernels.get_signed(progenitor, package, quiet=(debug_level < 1)) | ||
305 | 276 | else: | ||
306 | 277 | signed_pkg = meta_kernels.get_signed(release, package, quiet=(debug_level < 1)) | ||
307 | 278 | if signed_pkg: | ||
308 | 279 | if signed_pkg not in packages: | ||
309 | 280 | packages[signed_pkg] = { | ||
310 | 281 | 'Priority': packages[package]['Priority'], | ||
311 | 282 | 'Tags': packages[package]['Tags'], | ||
312 | 283 | 'Releases': {} | ||
313 | 284 | } | ||
314 | 285 | if release not in packages[signed_pkg]['Releases']: | ||
315 | 286 | packages[signed_pkg]['Releases'][release] = \ | ||
316 | 287 | duplicate_package_status(release, signed_pkg, packages[package]['Releases'][release], cache) | ||
317 | 288 | |||
318 | 289 | # if subproject is based on an ubuntu release | ||
319 | 290 | for pkg in packages: | ||
320 | 291 | # if subproject is DNE for a given package, then copy parent's status | ||
321 | 292 | for rel in packages[pkg]['Releases']: | ||
322 | 293 | parent = release_parent(rel) | ||
323 | 294 | if parent and parent in packages[pkg]['Releases']: | ||
324 | 295 | if packages[pkg]['Releases'][parent]['status'] != 'not-applicable' and packages[pkg]['Releases'][rel]['status'] == 'not-applicable': | ||
325 | 296 | packages[pkg]['Releases'][rel] = \ | ||
326 | 297 | duplicate_package_status(parent, pkg, packages[pkg]['Releases'][parent], cache) | ||
327 | 298 | # this is needed for update instructions | ||
328 | 299 | progenitor = release_progenitor(parent) | ||
329 | 300 | if progenitor and progenitor in packages[pkg]['Releases']: | ||
330 | 301 | if packages[pkg]['Releases'][parent]['status'] == packages[pkg]['Releases'][progenitor]['status']: | ||
331 | 302 | packages[pkg]['Releases'][rel]['parent'] = progenitor | ||
332 | 303 | else: | ||
333 | 304 | packages[pkg]['Releases'][rel]['parent'] = parent | ||
334 | 305 | else: | ||
335 | 306 | packages[pkg]['Releases'][rel]['parent'] = parent | ||
336 | 307 | # if supported release not in CVE file, then copy parent's status | ||
337 | 308 | for rel in supported_releases: | ||
338 | 309 | if rel not in packages[pkg]['Releases']: | ||
339 | 310 | parent = release_parent(rel) | ||
340 | 311 | if parent and parent not in packages[pkg]['Releases']: | ||
341 | 312 | parent = release_parent(parent) | ||
342 | 313 | |||
343 | 314 | if not parent or parent not in packages[pkg]['Releases']: | ||
344 | 315 | continue | ||
345 | 316 | |||
346 | 317 | packages[pkg]['Releases'][rel] = \ | ||
347 | 318 | duplicate_package_status(parent, pkg, packages[pkg]['Releases'][parent], cache) | ||
348 | 319 | packages[pkg]['Releases'][rel]['parent'] = parent | ||
349 | 320 | |||
350 | 321 | return {'header': cve_header_data, 'packages': packages} | ||
351 | 322 | |||
352 | 323 | |||
353 | 324 | def get_cve_url(filepath): | ||
354 | 325 | """ returns a url to CVE data from a filepath """ | ||
355 | 326 | path = os.path.realpath(filepath).split(os.sep) | ||
356 | 327 | url = "https://ubuntu.com/security" | ||
357 | 328 | cve = path[-1] | ||
358 | 329 | return "%s/%s" % (url, cve) | ||
368 | 330 | 132 | ||
369 | 331 | 133 | ||
370 | 332 | def warn(message): | 134 | def warn(message): |
371 | @@ -343,17 +145,6 @@ def debug(message): | |||
372 | 343 | if debug_level > 0: | 145 | if debug_level > 0: |
373 | 344 | sys.stdout.write('\rDEBUG: {0}\n'.format(message)) | 146 | sys.stdout.write('\rDEBUG: {0}\n'.format(message)) |
374 | 345 | 147 | ||
375 | 346 | def progress_bar(current, total, size=20): | ||
376 | 347 | """ show a simple progress bar on the CLI """ | ||
377 | 348 | current_percent = float(current) / total | ||
378 | 349 | hashes = '#' * int(round(current_percent * size)) | ||
379 | 350 | spaces = ' ' * (size - len(hashes)) | ||
380 | 351 | sys.stdout.write('\rProgress: [{0}] {1}% ({2} of {3} CVEs processed)'.format(hashes + spaces, int(round(current_percent * 100)), current, total)) | ||
381 | 352 | if (current == total): | ||
382 | 353 | sys.stdout.write('\n') | ||
383 | 354 | |||
384 | 355 | sys.stdout.flush() | ||
385 | 356 | |||
386 | 357 | def prepend_usn_to_id(usn_database, usn_id): | 148 | def prepend_usn_to_id(usn_database, usn_id): |
387 | 358 | if re.search(r'^[0-9]+-[0-9]$', usn_id): | 149 | if re.search(r'^[0-9]+-[0-9]$', usn_id): |
388 | 359 | usn_database[usn_id]['id'] = 'USN-' + usn_id | 150 | usn_database[usn_id]['id'] = 'USN-' + usn_id |
389 | @@ -381,15 +172,15 @@ def get_usn_database(usn_db_dir): | |||
390 | 381 | 172 | ||
391 | 382 | # Usage: | 173 | # Usage: |
392 | 383 | # for a given release only: | 174 | # for a given release only: |
394 | 384 | # ./generate-oval --usn-oval --usn-db-dir ~/usndb --usn-oval-release=focal --output-dir /tmp/oval_usn | 175 | # ./generate-oval --type usn --usn-db-dir ~/usndb --oval-releases=focal --output-dir /tmp/oval_usn |
395 | 385 | # for all the releases: | 176 | # for all the releases: |
397 | 386 | # ./generate-oval --usn-oval --usn-db-dir ~/usndb --output-dir /tmp/oval_usn | 177 | # ./generate-oval --type usn --usn-db-dir ~/usndb --output-dir /tmp/oval_usn |
398 | 387 | # for a specific release and USN-number | 178 | # for a specific release and USN-number |
400 | 388 | # ./generate-oval --usn-oval --usn-db-dir ~/usndb --usn-oval-release=focal --usn-number=1234 | 179 | # ./generate-oval --type usn --usn-db-dir ~/usndb --oval-releases=focal --usn-number=1234 |
401 | 389 | # WARNING: | 180 | # WARNING: |
402 | 390 | # be sure the release you are passing is in the usn-number passed | 181 | # be sure the release you are passing is in the usn-number passed |
403 | 391 | # otherwise it will generate an oval file without the usn info. | 182 | # otherwise it will generate an oval file without the usn info. |
405 | 392 | def generate_oval_usn(outdir, usn, usn_releases, cve_dir, usn_db_dir, no_progress, ociprefix=None, ocioutdir=None): | 183 | def generate_oval_usn(outdir, usn, usn_releases, cves, usn_db_dir, no_progress, ociprefix, ocioutdir): |
406 | 393 | # Get the usn database.json data | 184 | # Get the usn database.json data |
407 | 394 | usn_database = get_usn_database(usn_db_dir) | 185 | usn_database = get_usn_database(usn_db_dir) |
408 | 395 | if not usn_database: | 186 | if not usn_database: |
409 | @@ -404,33 +195,27 @@ def generate_oval_usn(outdir, usn, usn_releases, cve_dir, usn_db_dir, no_progres | |||
410 | 404 | valid_releases = [] | 195 | valid_releases = [] |
411 | 405 | 196 | ||
412 | 406 | # Check or generate valid releases | 197 | # Check or generate valid releases |
420 | 407 | if usn_releases: | 198 | valid_releases = list(filter(lambda release: product_series(release)[0] == PRODUCT_UBUNTU, usn_releases)) |
414 | 408 | for usn_release in usn_releases: | ||
415 | 409 | if usn_release not in supported_releases: | ||
416 | 410 | error(f"Invalid release name '{usn_release}'.") | ||
417 | 411 | valid_releases = usn_releases | ||
418 | 412 | else: | ||
419 | 413 | valid_releases = list(filter(lambda release: product_series(release)[0] == PRODUCT_UBUNTU, supported_releases)) | ||
421 | 414 | 199 | ||
422 | 415 | if not no_progress: | 200 | if not no_progress: |
423 | 416 | print('[*] Generating OVAL USN for packages in releases', ', '.join(valid_releases)) | 201 | print('[*] Generating OVAL USN for packages in releases', ', '.join(valid_releases)) |
424 | 417 | 202 | ||
425 | 418 | for release in valid_releases: | 203 | for release in valid_releases: |
427 | 419 | ovals.append(oval_lib.OvalGeneratorUSN(release, release_name(release), outdir, cve_dir)) | 204 | ovals.append(oval_lib.OvalGeneratorUSN(release, release_name(release), outdir, cves)) |
428 | 420 | # Also produce oval generator object for OCI | 205 | # Also produce oval generator object for OCI |
429 | 421 | if ocioutdir: | 206 | if ocioutdir: |
430 | 422 | ovals.append(oval_lib.OvalGeneratorUSN(release, release_name(release), ocioutdir, | 207 | ovals.append(oval_lib.OvalGeneratorUSN(release, release_name(release), ocioutdir, |
432 | 423 | cve_dir, ociprefix, 'oci')) | 208 | cves, ociprefix, 'oci')) |
433 | 424 | # Generate OVAL USN data | 209 | # Generate OVAL USN data |
434 | 425 | if usn: | 210 | if usn: |
435 | 426 | prepend_usn_to_id(usn_database, usn) | 211 | prepend_usn_to_id(usn_database, usn) |
436 | 427 | for oval in ovals: | 212 | for oval in ovals: |
438 | 428 | oval.generate_usn_oval(usn_database[usn], usn_database[usn]['id'], cve_dir) | 213 | oval.generate_usn_oval(usn_database[usn], usn_database[usn]['id'], cves) |
439 | 429 | else: | 214 | else: |
440 | 430 | for usn in sorted(usn_database.keys()): | 215 | for usn in sorted(usn_database.keys()): |
441 | 431 | prepend_usn_to_id(usn_database, usn) | 216 | prepend_usn_to_id(usn_database, usn) |
442 | 432 | for oval in ovals: | 217 | for oval in ovals: |
444 | 433 | oval.generate_usn_oval(usn_database[usn], usn_database[usn]['id'], cve_dir) | 218 | oval.generate_usn_oval(usn_database[usn], usn_database[usn]['id'], cves) |
445 | 434 | 219 | ||
446 | 435 | for oval in ovals: | 220 | for oval in ovals: |
447 | 436 | oval.write_oval_elements() | 221 | oval.write_oval_elements() |
448 | @@ -452,21 +237,20 @@ def filter_releases_for_output(releases, ov): | |||
449 | 452 | return output_releases | 237 | return output_releases |
450 | 453 | 238 | ||
451 | 454 | 239 | ||
453 | 455 | def generate_oval_package(releases, outdir, cve_prefix_dir, pkg_cache, cve_cache, oci, no_progress, packages, pathnames, fixed_only, ocioutdir=None, expand=False): | 240 | def generate_oval_package(releases, outdir, cves, pkg_cache, cve_cache, oci, no_progress, packages, fixed_only, ocioutdir, expand): |
454 | 456 | if not no_progress: | 241 | if not no_progress: |
455 | 457 | print('[*] Initiating OVAL Generation for PKG') | 242 | print('[*] Initiating OVAL Generation for PKG') |
456 | 458 | 243 | ||
457 | 459 | ov = oval_lib.OvalGeneratorPkg( | 244 | ov = oval_lib.OvalGeneratorPkg( |
465 | 460 | releases, | 245 | releases, |
466 | 461 | pathnames, | 246 | cves, |
467 | 462 | packages, | 247 | packages, |
468 | 463 | not no_progress, | 248 | not no_progress, |
469 | 464 | pkg_cache=pkg_cache, | 249 | pkg_cache=pkg_cache, |
470 | 465 | fixed_only=fixed_only, | 250 | fixed_only=fixed_only, |
471 | 466 | cve_cache=cve_cache, | 251 | cve_cache=cve_cache, |
472 | 467 | oval_format='dpkg', | 252 | oval_format='dpkg', |
475 | 468 | outdir=outdir, | 253 | outdir=outdir, |
474 | 469 | cve_prefix_dir=cve_prefix_dir, | ||
476 | 470 | expand=expand | 254 | expand=expand |
477 | 471 | ) | 255 | ) |
478 | 472 | 256 | ||
479 | @@ -485,21 +269,20 @@ def generate_oval_package(releases, outdir, cve_prefix_dir, pkg_cache, cve_cache | |||
480 | 485 | if not no_progress: | 269 | if not no_progress: |
481 | 486 | print(f'[X] Done generating OVAL PKG for packages in releases {", ".join(output_releases)}') | 270 | print(f'[X] Done generating OVAL PKG for packages in releases {", ".join(output_releases)}') |
482 | 487 | 271 | ||
484 | 488 | def generate_oval_cve(releases, outdir, cve_prefix_dir, pkg_cache, cve_cache, oci, no_progress, packages, pathnames, fixed_only, ocioutdir=None, expand=False): | 272 | def generate_oval_cve(releases, outdir, cves, pkg_cache, cve_cache, oci, no_progress, packages, fixed_only, ocioutdir, expand): |
485 | 489 | if not no_progress: | 273 | if not no_progress: |
486 | 490 | print('[*] Initiating OVAL Generation for CVE') | 274 | print('[*] Initiating OVAL Generation for CVE') |
487 | 491 | 275 | ||
488 | 492 | ov = oval_lib.OvalGeneratorCVE( | 276 | ov = oval_lib.OvalGeneratorCVE( |
492 | 493 | releases, | 277 | releases, |
493 | 494 | pathnames, | 278 | cves, |
494 | 495 | packages, | 279 | packages, |
495 | 496 | not no_progress, | 280 | not no_progress, |
499 | 497 | pkg_cache=pkg_cache, | 281 | pkg_cache=pkg_cache, |
500 | 498 | fixed_only=fixed_only, | 282 | fixed_only=fixed_only, |
501 | 499 | cve_cache=cve_cache, | 283 | cve_cache=cve_cache, |
502 | 500 | oval_format='dpkg', | 284 | oval_format='dpkg', |
505 | 501 | outdir=outdir, | 285 | outdir=outdir, |
504 | 502 | cve_prefix_dir=cve_prefix_dir, | ||
506 | 503 | expand=expand | 286 | expand=expand |
507 | 504 | ) | 287 | ) |
508 | 505 | 288 | ||
509 | diff --git a/scripts/oval_lib.py b/scripts/oval_lib.py | |||
510 | index d60c6dc..a974eaf 100644 | |||
511 | --- a/scripts/oval_lib.py | |||
512 | +++ b/scripts/oval_lib.py | |||
513 | @@ -29,7 +29,6 @@ import tempfile | |||
514 | 29 | import collections | 29 | import collections |
515 | 30 | import glob | 30 | import glob |
516 | 31 | import xml.etree.cElementTree as etree | 31 | import xml.etree.cElementTree as etree |
517 | 32 | import json | ||
518 | 33 | from xml.dom import minidom | 32 | from xml.dom import minidom |
519 | 34 | from typing import Tuple # Needed because of Python < 3.9 and to also support < 3.7 | 33 | from typing import Tuple # Needed because of Python < 3.9 and to also support < 3.7 |
520 | 35 | 34 | ||
521 | @@ -172,7 +171,7 @@ def get_binarypkgs(cache, source_name, release): | |||
522 | 172 | """ return a list of binary packages from the source package version """ | 171 | """ return a list of binary packages from the source package version """ |
523 | 173 | packages_to_ignore = ("-dev", "-doc", "-dbg", "-dbgsym", "-udeb", "-locale-") | 172 | packages_to_ignore = ("-dev", "-doc", "-dbg", "-dbgsym", "-udeb", "-locale-") |
524 | 174 | binaries_map = collections.defaultdict(dict) | 173 | binaries_map = collections.defaultdict(dict) |
526 | 175 | 174 | ||
527 | 176 | rel = get_real_release(cache, source_name, release) | 175 | rel = get_real_release(cache, source_name, release) |
528 | 177 | if not rel: return None, None | 176 | if not rel: return None, None |
529 | 178 | 177 | ||
530 | @@ -316,7 +315,7 @@ class CVE: | |||
531 | 316 | self.bugs.append(url) | 315 | self.bugs.append(url) |
532 | 317 | elif url: | 316 | elif url: |
533 | 318 | self.references.append(url) | 317 | self.references.append(url) |
535 | 319 | 318 | ||
536 | 320 | for bug in info['Bugs'].split('\n'): | 319 | for bug in info['Bugs'].split('\n'): |
537 | 321 | if bug: | 320 | if bug: |
538 | 322 | self.bugs.append(bug) | 321 | self.bugs.append(bug) |
539 | @@ -331,7 +330,7 @@ class CVE: | |||
540 | 331 | for pkg in self.pkgs: | 330 | for pkg in self.pkgs: |
541 | 332 | if pkg.rel not in releases: | 331 | if pkg.rel not in releases: |
542 | 333 | continue | 332 | continue |
544 | 334 | 333 | ||
545 | 335 | if pkg.name not in pkg_rel: | 334 | if pkg.name not in pkg_rel: |
546 | 336 | pkg_rel[pkg.name] = pkg | 335 | pkg_rel[pkg.name] = pkg |
547 | 337 | else: | 336 | else: |
548 | @@ -356,7 +355,7 @@ class CVE: | |||
549 | 356 | 355 | ||
550 | 357 | if pkg.name in pkg_rel and pkg_rel[pkg.name].rel == pkg.rel: | 356 | if pkg.name in pkg_rel and pkg_rel[pkg.name].rel == pkg.rel: |
551 | 358 | pkgs.append(pkg) | 357 | pkgs.append(pkg) |
553 | 359 | 358 | ||
554 | 360 | return pkgs | 359 | return pkgs |
555 | 361 | 360 | ||
556 | 362 | 361 | ||
557 | @@ -429,7 +428,7 @@ class Package: | |||
558 | 429 | 428 | ||
559 | 430 | def version_exists(self, source_version): | 429 | def version_exists(self, source_version): |
560 | 431 | return source_version in self.versions_binaries | 430 | return source_version in self.versions_binaries |
562 | 432 | 431 | ||
563 | 433 | def all_binaries_same_version(self, source_version): | 432 | def all_binaries_same_version(self, source_version): |
564 | 434 | if source_version not in self.versions_binaries: | 433 | if source_version not in self.versions_binaries: |
565 | 435 | return len(self.versions_binaries[self.earliest_version]) <= 1 | 434 | return len(self.versions_binaries[self.earliest_version]) <= 1 |
566 | @@ -514,7 +513,7 @@ class OvalGenerator: | |||
567 | 514 | supported_oval_elements = ('definition', 'test', 'object', 'state', 'variable') | 513 | supported_oval_elements = ('definition', 'test', 'object', 'state', 'variable') |
568 | 515 | generator_version = '2' | 514 | generator_version = '2' |
569 | 516 | oval_schema_version = '5.11.1' | 515 | oval_schema_version = '5.11.1' |
571 | 517 | def __init__(self, type, releases, cve_paths, packages, progress, pkg_cache, fixed_only=True, cve_cache=None, cve_prefix_dir=None, outdir='./', oval_format='dpkg', expand=False) -> None: | 516 | def __init__(self, type, releases, cve_paths, packages, progress, pkg_cache, fixed_only=True, cve_cache=None, outdir='./', oval_format='dpkg', expand=False) -> None: |
572 | 518 | self.releases = releases | 517 | self.releases = releases |
573 | 519 | self.output_dir = outdir | 518 | self.output_dir = outdir |
574 | 520 | self.oval_format = oval_format | 519 | self.oval_format = oval_format |
575 | @@ -524,7 +523,7 @@ class OvalGenerator: | |||
576 | 524 | self.pkg_cache = pkg_cache | 523 | self.pkg_cache = pkg_cache |
577 | 525 | self.cve_paths = cve_paths | 524 | self.cve_paths = cve_paths |
578 | 526 | self.fixed_only = fixed_only | 525 | self.fixed_only = fixed_only |
580 | 527 | self.packages, self.cves = self._load(cve_prefix_dir, packages) | 526 | self.packages, self.cves = self._load(packages) |
581 | 528 | self.expand = expand | 527 | self.expand = expand |
582 | 529 | 528 | ||
583 | 530 | def _init_ids(self, release): | 529 | def _init_ids(self, release): |
584 | @@ -532,7 +531,7 @@ class OvalGenerator: | |||
585 | 532 | self.release = release | 531 | self.release = release |
586 | 533 | self.release_codename = cve_lib.release_progenitor(self.release) if cve_lib.release_progenitor(self.release) else self.release.replace('/', '_') | 532 | self.release_codename = cve_lib.release_progenitor(self.release) if cve_lib.release_progenitor(self.release) else self.release.replace('/', '_') |
587 | 534 | self.release_name = cve_lib.release_name(self.release) | 533 | self.release_name = cve_lib.release_name(self.release) |
589 | 535 | 534 | ||
590 | 536 | self.parent_releases = list() | 535 | self.parent_releases = list() |
591 | 537 | current_release = self.release | 536 | current_release = self.release |
592 | 538 | while(cve_lib.release_parent(current_release)): | 537 | while(cve_lib.release_parent(current_release)): |
593 | @@ -540,7 +539,7 @@ class OvalGenerator: | |||
594 | 540 | if current_release != self.release and \ | 539 | if current_release != self.release and \ |
595 | 541 | current_release not in self.parent_releases: | 540 | current_release not in self.parent_releases: |
596 | 542 | self.parent_releases.append(current_release) | 541 | self.parent_releases.append(current_release) |
598 | 543 | 542 | ||
599 | 544 | self.ns = 'oval:com.ubuntu.{0}'.format(self.release_codename) | 543 | self.ns = 'oval:com.ubuntu.{0}'.format(self.release_codename) |
600 | 545 | self.id = 100 | 544 | self.id = 100 |
601 | 546 | self.host_def_id = self.id | 545 | self.host_def_id = self.id |
602 | @@ -564,7 +563,7 @@ class OvalGenerator: | |||
603 | 564 | self.output_filepath = \ | 563 | self.output_filepath = \ |
604 | 565 | '{0}com.ubuntu.{1}.{2}.oval.xml'.format('oci.' if self.oval_format == 'oci' else '', self.release.replace('/', '_'), self.generator_type) | 564 | '{0}com.ubuntu.{1}.{2}.oval.xml'.format('oci.' if self.oval_format == 'oci' else '', self.release.replace('/', '_'), self.generator_type) |
605 | 566 | 565 | ||
607 | 567 | 566 | ||
608 | 568 | def _add_structure(self, root) -> None: | 567 | def _add_structure(self, root) -> None: |
609 | 569 | structure = {} | 568 | structure = {} |
610 | 570 | for element in self.supported_oval_elements: | 569 | for element in self.supported_oval_elements: |
611 | @@ -756,14 +755,14 @@ class OvalGenerator: | |||
612 | 756 | pkg_obj = packages[package_name] | 755 | pkg_obj = packages[package_name] |
613 | 757 | cve.add_pkg(pkg_obj, release, cve_data['pkgs'][package_name][release][0],cve_data['pkgs'][package_name][release][1], self.expand) | 756 | cve.add_pkg(pkg_obj, release, cve_data['pkgs'][package_name][release][0],cve_data['pkgs'][package_name][release][1], self.expand) |
614 | 758 | 757 | ||
616 | 759 | def _load(self, cve_prefix_dir, packages_filter=None) -> None: | 758 | def _load(self, packages_filter=None) -> None: |
617 | 760 | cve_lib.load_external_subprojects() | 759 | cve_lib.load_external_subprojects() |
618 | 761 | 760 | ||
620 | 762 | cve_paths = [] | 761 | path_to_cves = [] |
621 | 763 | for pathname in self.cve_paths: | 762 | for pathname in self.cve_paths: |
623 | 764 | cve_paths = cve_paths + glob.glob(os.path.join(cve_prefix_dir, pathname)) | 763 | path_to_cves = path_to_cves + glob.glob(pathname) |
624 | 765 | 764 | ||
626 | 766 | cve_paths.sort(key=lambda cve: | 765 | path_to_cves.sort(key=lambda cve: |
627 | 767 | (int(cve.split('/')[-1].split('-')[1]), int(cve.split('/')[-1].split('-')[2])) \ | 766 | (int(cve.split('/')[-1].split('-')[1]), int(cve.split('/')[-1].split('-')[2])) \ |
628 | 768 | if cve.split('/')[-1].split('-')[2].isnumeric() \ | 767 | if cve.split('/')[-1].split('-')[2].isnumeric() \ |
629 | 769 | else (int(cve.split('/')[-1].split('-')[1]), 0) | 768 | else (int(cve.split('/')[-1].split('-')[1]), 0) |
630 | @@ -790,12 +789,12 @@ class OvalGenerator: | |||
631 | 790 | if release not in cve_lib.external_releases else {} | 789 | if release not in cve_lib.external_releases else {} |
632 | 791 | 790 | ||
633 | 792 | i = 0 | 791 | i = 0 |
635 | 793 | for cve_path in cve_paths: | 792 | for cve_path in path_to_cves: |
636 | 794 | cve_number = cve_path.rsplit('/', 1)[1] | 793 | cve_number = cve_path.rsplit('/', 1)[1] |
637 | 795 | i += 1 | 794 | i += 1 |
638 | 796 | 795 | ||
639 | 797 | if self.progress: | 796 | if self.progress: |
641 | 798 | print(f'[{i:5}/{len(cve_paths)}] Processing {cve_number:18}', end='\r') | 797 | print(f'[{i:5}/{len(path_to_cves)}] Processing {cve_number:18}', end='\r') |
642 | 799 | 798 | ||
643 | 800 | if not cve_number in self.cve_cache: | 799 | if not cve_number in self.cve_cache: |
644 | 801 | self.cve_cache[cve_number] = cve_lib.load_cve(cve_path) | 800 | self.cve_cache[cve_number] = cve_lib.load_cve(cve_path) |
645 | @@ -849,7 +848,7 @@ class OvalGenerator: | |||
646 | 849 | extend_definition.set("applicability_check", "true") | 848 | extend_definition.set("applicability_check", "true") |
647 | 850 | 849 | ||
648 | 851 | return criteria | 850 | return criteria |
650 | 852 | 851 | ||
651 | 853 | def _generate_definition_object(self, object) -> etree.Element: | 852 | def _generate_definition_object(self, object) -> etree.Element: |
652 | 854 | id = f"{self.ns}:def:{self.definition_id}" | 853 | id = f"{self.ns}:def:{self.definition_id}" |
653 | 855 | definition = etree.Element("definition") | 854 | definition = etree.Element("definition") |
654 | @@ -889,7 +888,7 @@ class OvalGenerator: | |||
655 | 889 | cve_tag.set('usns', ','.join(cve.usns)) | 888 | cve_tag.set('usns', ','.join(cve.usns)) |
656 | 890 | 889 | ||
657 | 891 | return cve_tag | 890 | return cve_tag |
659 | 892 | 891 | ||
660 | 893 | def _generate_var_element(self, comment, id, binaries) -> etree.Element: | 892 | def _generate_var_element(self, comment, id, binaries) -> etree.Element: |
661 | 894 | var = etree.Element("constant_variable", | 893 | var = etree.Element("constant_variable", |
662 | 895 | attrib={ | 894 | attrib={ |
663 | @@ -1323,9 +1322,9 @@ class OvalGenerator: | |||
664 | 1323 | 1322 | ||
665 | 1324 | 1323 | ||
666 | 1325 | class OvalGeneratorPkg(OvalGenerator): | 1324 | class OvalGeneratorPkg(OvalGenerator): |
668 | 1326 | def __init__(self, releases, cve_paths, packages, progress, pkg_cache, fixed_only=True, cve_cache=None, cve_prefix_dir=None, outdir='./', oval_format='dpkg',expand=False) -> None: | 1325 | def __init__(self, releases, cve_paths, packages, progress, pkg_cache, fixed_only=True, cve_cache=None, outdir='./', oval_format='dpkg',expand=False) -> None: |
669 | 1327 | self.expand = expand | 1326 | self.expand = expand |
671 | 1328 | super().__init__('pkg', releases, cve_paths, packages, progress, pkg_cache, fixed_only, cve_cache, cve_prefix_dir, outdir, oval_format, expand) | 1327 | super().__init__('pkg', releases, cve_paths, packages, progress, pkg_cache, fixed_only, cve_cache, outdir, oval_format, expand) |
672 | 1329 | 1328 | ||
673 | 1330 | def _generate_advisory(self, package: Package) -> etree.Element: | 1329 | def _generate_advisory(self, package: Package) -> etree.Element: |
674 | 1331 | advisory = etree.Element("advisory") | 1330 | advisory = etree.Element("advisory") |
675 | @@ -1431,7 +1430,7 @@ class OvalGeneratorPkg(OvalGenerator): | |||
676 | 1431 | binary_id_version = binary_version | 1430 | binary_id_version = binary_version |
677 | 1432 | 1431 | ||
678 | 1433 | binaries_ids.setdefault(binary_id_version, None) | 1432 | binaries_ids.setdefault(binary_id_version, None) |
680 | 1434 | binaries_id = binaries_ids[binary_id_version] | 1433 | binaries_id = binaries_ids[binary_id_version] |
681 | 1435 | test, obj, var, state = self._generate_elements(package, binaries, binary_version, pkg_rel_entry, binaries_id) | 1434 | test, obj, var, state = self._generate_elements(package, binaries, binary_version, pkg_rel_entry, binaries_id) |
682 | 1436 | 1435 | ||
683 | 1437 | if state: | 1436 | if state: |
684 | @@ -1451,7 +1450,7 @@ class OvalGeneratorPkg(OvalGenerator): | |||
685 | 1451 | 1450 | ||
686 | 1452 | self._increase_id(is_definition=True) | 1451 | self._increase_id(is_definition=True) |
687 | 1453 | 1452 | ||
689 | 1454 | def _populate_kernel_pkg(self, package, root_element, running_kernel_id): | 1453 | def _populate_kernel_pkg(self, package, root_element, running_kernel_id): |
690 | 1455 | for cve in package.cves: | 1454 | for cve in package.cves: |
691 | 1456 | pkg_rel_entry = cve.pkg_rel_entries[str(package)] | 1455 | pkg_rel_entry = cve.pkg_rel_entries[str(package)] |
692 | 1457 | version_to_check = package.get_version_to_check(pkg_rel_entry.fixed_version) | 1456 | version_to_check = package.get_version_to_check(pkg_rel_entry.fixed_version) |
693 | @@ -1482,7 +1481,7 @@ class OvalGeneratorPkg(OvalGenerator): | |||
694 | 1482 | cve_added = True | 1481 | cve_added = True |
695 | 1483 | 1482 | ||
696 | 1484 | # Determine if CVE is linked to existing test_ref | 1483 | # Determine if CVE is linked to existing test_ref |
698 | 1485 | test_ref_id = self.definition_id | 1484 | test_ref_id = self.definition_id |
699 | 1486 | if fixed_versions.get(pkg_rel_entry.fixed_version, False): | 1485 | if fixed_versions.get(pkg_rel_entry.fixed_version, False): |
700 | 1487 | test_ref_id = fixed_versions[pkg_rel_entry.fixed_version] | 1486 | test_ref_id = fixed_versions[pkg_rel_entry.fixed_version] |
701 | 1488 | self._add_test_ref_to_cve_tag(test_ref_id, cve, definition_element) | 1487 | self._add_test_ref_to_cve_tag(test_ref_id, cve, definition_element) |
702 | @@ -1513,7 +1512,7 @@ class OvalGeneratorPkg(OvalGenerator): | |||
703 | 1513 | all_pkgs = dict() | 1512 | all_pkgs = dict() |
704 | 1514 | for parent_release in self.parent_releases[::-1]: | 1513 | for parent_release in self.parent_releases[::-1]: |
705 | 1515 | all_pkgs.update(self.packages[parent_release]) | 1514 | all_pkgs.update(self.packages[parent_release]) |
707 | 1516 | 1515 | ||
708 | 1517 | all_pkgs.update(self.packages[self.release]) | 1516 | all_pkgs.update(self.packages[self.release]) |
709 | 1518 | 1517 | ||
710 | 1519 | for pkg in all_pkgs: | 1518 | for pkg in all_pkgs: |
711 | @@ -1529,9 +1528,9 @@ class OvalGeneratorPkg(OvalGenerator): | |||
712 | 1529 | self._write_oval_xml(xml_tree, root_element) | 1528 | self._write_oval_xml(xml_tree, root_element) |
713 | 1530 | 1529 | ||
714 | 1531 | class OvalGeneratorCVE(OvalGenerator): | 1530 | class OvalGeneratorCVE(OvalGenerator): |
716 | 1532 | def __init__(self, releases, cve_paths, packages, progress, pkg_cache, fixed_only=True, cve_cache=None, cve_prefix_dir=None, outdir='./', oval_format='dpkg', expand=False) -> None: | 1531 | def __init__(self, releases, cve_paths, packages, progress, pkg_cache, fixed_only=True, cve_cache=None, outdir='./', oval_format='dpkg', expand=False) -> None: |
717 | 1533 | self.expand = expand | 1532 | self.expand = expand |
719 | 1534 | super().__init__('cve', releases, cve_paths, packages, progress, pkg_cache, fixed_only, cve_cache, cve_prefix_dir, outdir, oval_format, expand) | 1533 | super().__init__('cve', releases, cve_paths, packages, progress, pkg_cache, fixed_only, cve_cache, outdir, oval_format, expand) |
720 | 1535 | 1534 | ||
721 | 1536 | # For CVE OVAL, the definition ID is generated | 1535 | # For CVE OVAL, the definition ID is generated |
722 | 1537 | # from the CVE ID | 1536 | # from the CVE ID |
723 | @@ -1551,7 +1550,7 @@ class OvalGeneratorCVE(OvalGenerator): | |||
724 | 1551 | if cve.assigned_to: | 1550 | if cve.assigned_to: |
725 | 1552 | assigned_to = etree.SubElement(advisory, "assigned_to") | 1551 | assigned_to = etree.SubElement(advisory, "assigned_to") |
726 | 1553 | assigned_to.text = cve.assigned_to | 1552 | assigned_to.text = cve.assigned_to |
728 | 1554 | 1553 | ||
729 | 1555 | if cve.discoverd_by: | 1554 | if cve.discoverd_by: |
730 | 1556 | discoverd_by = etree.SubElement(advisory, "discoverd_by") | 1555 | discoverd_by = etree.SubElement(advisory, "discoverd_by") |
731 | 1557 | discoverd_by.text = cve.discoverd_by | 1556 | discoverd_by.text = cve.discoverd_by |
732 | @@ -1596,7 +1595,7 @@ class OvalGeneratorCVE(OvalGenerator): | |||
733 | 1596 | "ref_url": f'https://cve.mitre.org/cgi-bin/cvename.cgi?name={cve.number}' | 1595 | "ref_url": f'https://cve.mitre.org/cgi-bin/cvename.cgi?name={cve.number}' |
734 | 1597 | }) | 1596 | }) |
735 | 1598 | 1597 | ||
737 | 1599 | return reference | 1598 | return reference |
738 | 1600 | 1599 | ||
739 | 1601 | def prepare_instructions(self, instruction, cve: CVE, product_description, package: Package, fixed_version): | 1600 | def prepare_instructions(self, instruction, cve: CVE, product_description, package: Package, fixed_version): |
740 | 1602 | if "LSN" in cve.number: | 1601 | if "LSN" in cve.number: |
741 | @@ -1729,13 +1728,13 @@ class OvalGeneratorCVE(OvalGenerator): | |||
742 | 1729 | pkg_added = True | 1728 | pkg_added = True |
743 | 1730 | else: | 1729 | else: |
744 | 1731 | pkg_added = self._populate_pkg(cve, pkg, root_element, definition_element, pkg_cache, fixed_versions) | 1730 | pkg_added = self._populate_pkg(cve, pkg, root_element, definition_element, pkg_cache, fixed_versions) |
746 | 1732 | 1731 | ||
747 | 1733 | if pkg_rel_entry.status == 'fixed' and pkg_added: | 1732 | if pkg_rel_entry.status == 'fixed' and pkg_added: |
748 | 1734 | product_description = cve_lib.get_subproject_description(pkg_rel_entry.release) | 1733 | product_description = cve_lib.get_subproject_description(pkg_rel_entry.release) |
749 | 1735 | instructions = self.prepare_instructions(instructions, cve, product_description, pkg, pkg_rel_entry.fixed_version) | 1734 | instructions = self.prepare_instructions(instructions, cve, product_description, pkg, pkg_rel_entry.fixed_version) |
750 | 1736 | 1735 | ||
751 | 1737 | cve_added = cve_added | pkg_added | 1736 | cve_added = cve_added | pkg_added |
753 | 1738 | 1737 | ||
754 | 1739 | if cve_added: | 1738 | if cve_added: |
755 | 1740 | definitions = root_element.find("definitions") | 1739 | definitions = root_element.find("definitions") |
756 | 1741 | metadata = definition_element.find('metadata') | 1740 | metadata = definition_element.find('metadata') |
757 | @@ -1780,8 +1779,8 @@ class OvalGeneratorCVE(OvalGenerator): | |||
758 | 1780 | self._write_oval_xml(xml_tree, root_element) | 1779 | self._write_oval_xml(xml_tree, root_element) |
759 | 1781 | 1780 | ||
760 | 1782 | class OvalGeneratorUSNs(OvalGenerator): | 1781 | class OvalGeneratorUSNs(OvalGenerator): |
763 | 1783 | def __init__(self, releases, cve_paths, packages, progress, pkg_cache, usn_database, fixed_only=True, cve_cache=None, cve_prefix_dir=None, outdir='./', oval_format='dpkg') -> None: | 1782 | def __init__(self, releases, cve_paths, packages, progress, pkg_cache, usn_database, fixed_only=True, cve_cache=None, outdir='./', oval_format='dpkg') -> None: |
764 | 1784 | super().__init__('usn', releases, cve_paths, packages, progress, pkg_cache, fixed_only, cve_cache, cve_prefix_dir, outdir, oval_format) | 1783 | super().__init__('usn', releases, cve_paths, packages, progress, pkg_cache, fixed_only, cve_cache, outdir, oval_format) |
765 | 1785 | self.usns = self._load_usns(usn_database) | 1784 | self.usns = self._load_usns(usn_database) |
766 | 1786 | 1785 | ||
767 | 1787 | def _load_usns(self, usn_database): | 1786 | def _load_usns(self, usn_database): |
768 | @@ -1838,7 +1837,7 @@ class OvalGeneratorUSNs(OvalGenerator): | |||
769 | 1838 | platform = etree.SubElement(affected, "platform") | 1837 | platform = etree.SubElement(affected, "platform") |
770 | 1839 | 1838 | ||
771 | 1840 | reference = self._generate_reference(usn) | 1839 | reference = self._generate_reference(usn) |
773 | 1841 | metadata.append(reference) | 1840 | metadata.append(reference) |
774 | 1842 | advisory = self._generate_advisory(usn) | 1841 | advisory = self._generate_advisory(usn) |
775 | 1843 | metadata.append(reference) | 1842 | metadata.append(reference) |
776 | 1844 | metadata.append(advisory) | 1843 | metadata.append(advisory) |
777 | @@ -1920,7 +1919,7 @@ class OvalGeneratorUSNs(OvalGenerator): | |||
778 | 1920 | self._increase_id(is_definition=False) | 1919 | self._increase_id(is_definition=False) |
779 | 1921 | else: | 1920 | else: |
780 | 1922 | self._add_to_criteria(main_criteria, cache[package.name], depth=2, operator='OR') | 1921 | self._add_to_criteria(main_criteria, cache[package.name], depth=2, operator='OR') |
782 | 1923 | 1922 | ||
783 | 1924 | self._increase_id(is_definition=True) | 1923 | self._increase_id(is_definition=True) |
784 | 1925 | 1924 | ||
785 | 1926 | def generate_oval(self) -> None: | 1925 | def generate_oval(self) -> None: |
786 | @@ -1952,11 +1951,11 @@ class OvalGeneratorUSNs(OvalGenerator): | |||
787 | 1952 | self._populate_kernel_pkg(self.cves[cve], pkg, root_element, definition_element, running_kernel_id, pkg_cache, fixed_versions) | 1951 | self._populate_kernel_pkg(self.cves[cve], pkg, root_element, definition_element, running_kernel_id, pkg_cache, fixed_versions) |
788 | 1953 | else: | 1952 | else: |
789 | 1954 | self._populate_pkg(self.cves[cve], pkg, root_element, definition_element, pkg_cache, fixed_versions) | 1953 | self._populate_pkg(self.cves[cve], pkg, root_element, definition_element, pkg_cache, fixed_versions) |
791 | 1955 | 1954 | ||
792 | 1956 | if pkg_rel_entry.status == 'fixed' and pkg.binaries: | 1955 | if pkg_rel_entry.status == 'fixed' and pkg.binaries: |
793 | 1957 | product_description = cve_lib.get_subproject_description(pkg_rel_entry.release) | 1956 | product_description = cve_lib.get_subproject_description(pkg_rel_entry.release) |
794 | 1958 | instructions = prepare_instructions(instructions, self.cves[cve].number, product_description, {'binaries': pkg.binaries, 'fix-version': pkg_rel_entry.fixed_version}) | 1957 | instructions = prepare_instructions(instructions, self.cves[cve].number, product_description, {'binaries': pkg.binaries, 'fix-version': pkg_rel_entry.fixed_version}) |
796 | 1959 | 1958 | ||
797 | 1960 | metadata = definition_element.find('metadata') | 1959 | metadata = definition_element.find('metadata') |
798 | 1961 | metadata.find('description').text = metadata.find('description').text + instructions | 1960 | metadata.find('description').text = metadata.find('description').text + instructions |
799 | 1962 | definitions.append(definition_element) | 1961 | definitions.append(definition_element) |
800 | @@ -2467,14 +2466,13 @@ class OvalGeneratorUSN(): | |||
801 | 2467 | return constant_variable | 2466 | return constant_variable |
802 | 2468 | 2467 | ||
803 | 2469 | def get_cve_info_from_file(self, cve, cve_dir): | 2468 | def get_cve_info_from_file(self, cve, cve_dir): |
806 | 2470 | cve_active_file_path = os.path.join(cve_dir, 'active', cve) | 2469 | cve_file_path = "" |
807 | 2471 | cve_retired_file_path = os.path.join(cve_dir, 'retired', cve) | 2470 | for path in cve_dir: |
808 | 2471 | if os.path.exists(os.path.join(path, cve)): | ||
809 | 2472 | cve_file_path = os.path.join(path, cve) | ||
810 | 2473 | break | ||
811 | 2472 | 2474 | ||
817 | 2473 | if os.path.exists(cve_active_file_path): | 2475 | if not cve_file_path: |
813 | 2474 | cve_file_path = cve_active_file_path | ||
814 | 2475 | elif os.path.exists(cve_retired_file_path): | ||
815 | 2476 | cve_file_path = cve_retired_file_path | ||
816 | 2477 | else: | ||
818 | 2478 | return None | 2476 | return None |
819 | 2479 | 2477 | ||
820 | 2480 | cve_object = cve_lib.load_cve(cve_file_path) | 2478 | cve_object = cve_lib.load_cve(cve_file_path) |
821 | diff --git a/test/test_oval_lib_end_to_end.py b/test/test_oval_lib_end_to_end.py | |||
822 | index bfad6c4..db74957 100644 | |||
823 | --- a/test/test_oval_lib_end_to_end.py | |||
824 | +++ b/test/test_oval_lib_end_to_end.py | |||
825 | @@ -6,13 +6,13 @@ from test_utils import TestUtilities as util | |||
826 | 6 | from test_utils import OVALType | 6 | from test_utils import OVALType |
827 | 7 | class TestOvalLibEndToEnd: | 7 | class TestOvalLibEndToEnd: |
828 | 8 | @pytest.mark.parametrize("output_file,oscap_args", | 8 | @pytest.mark.parametrize("output_file,oscap_args", |
831 | 9 | [(util.focal_dpkg_file, ["--oval-release", "focal"]), | 9 | [(util.focal_dpkg_file, ["--oval-releases", "focal"]), |
832 | 10 | (util.xenial_dpkg_file, ["--oval-release", "xenial"])]) | 10 | (util.xenial_dpkg_file, ["--oval-releases", "xenial"])]) |
833 | 11 | def test_validate_entire_dpkg_oval(self, output_file, oscap_args): | 11 | def test_validate_entire_dpkg_oval(self, output_file, oscap_args): |
834 | 12 | """Coherence check of entire generated dpkg OVAL""" | 12 | """Coherence check of entire generated dpkg OVAL""" |
835 | 13 | write_file = util.rel_test_path + output_file | 13 | write_file = util.rel_test_path + output_file |
836 | 14 | 14 | ||
838 | 15 | subprocess.check_output(["./scripts/generate-oval", "--usn-oval", | 15 | subprocess.check_output(["./scripts/generate-oval", "--type=usn", |
839 | 16 | "--output-dir={}".format(util.rel_test_path)] + oscap_args, | 16 | "--output-dir={}".format(util.rel_test_path)] + oscap_args, |
840 | 17 | stderr=subprocess.STDOUT) | 17 | stderr=subprocess.STDOUT) |
841 | 18 | 18 | ||
842 | @@ -29,4 +29,4 @@ class TestOvalLibEndToEnd: | |||
843 | 29 | def test_validate_entire_oci_oval(self, dpkg_file, manifest, release): | 29 | def test_validate_entire_oci_oval(self, dpkg_file, manifest, release): |
844 | 30 | """Coherence check of entire generated oci OVAL""" | 30 | """Coherence check of entire generated oci OVAL""" |
845 | 31 | util.create_validate_oci(dpkg_file, "{}_full".format(release), | 31 | util.create_validate_oci(dpkg_file, "{}_full".format(release), |
847 | 32 | ["--oval-release", release], manifest, release, OVALType.USN) | 32 | ["--oval-releases", release], manifest, release, OVALType.USN) |
848 | diff --git a/test/test_oval_lib_functional.py b/test/test_oval_lib_functional.py | |||
849 | index 8b400fb..aad0116 100644 | |||
850 | --- a/test/test_oval_lib_functional.py | |||
851 | +++ b/test/test_oval_lib_functional.py | |||
852 | @@ -12,18 +12,18 @@ class TestOvalLibFunctional: | |||
853 | 12 | def test_multiple_binary_package(self, manifest): | 12 | def test_multiple_binary_package(self, manifest): |
854 | 13 | """Test a package with multiple binaries""" | 13 | """Test a package with multiple binaries""" |
855 | 14 | util.create_validate_oci(util.focal_dpkg_file, "focal_4410", | 14 | util.create_validate_oci(util.focal_dpkg_file, "focal_4410", |
857 | 15 | ["--usn-number", "4410-1", "--oval-release", "focal"], | 15 | ["--usn-number", "4410-1", "--oval-releases", "focal"], |
858 | 16 | manifest, "focal_mock_4410_vul", OVALType.USN) | 16 | manifest, "focal_mock_4410_vul", OVALType.USN) |
859 | 17 | 17 | ||
860 | 18 | @pytest.mark.parametrize("manifest", | 18 | @pytest.mark.parametrize("manifest", |
862 | 19 | # Binary is in manifest and not vulnerable | 19 | # Binary is in manifest and not vulnerable |
863 | 20 | [("bionic_mock_3642_not_vul"), | 20 | [("bionic_mock_3642_not_vul"), |
865 | 21 | # Binary is in manifest and vulnerable | 21 | # Binary is in manifest and vulnerable |
866 | 22 | ("bionic_mock_3642_vul")]) | 22 | ("bionic_mock_3642_vul")]) |
867 | 23 | def test_single_binary_package(self, manifest): | 23 | def test_single_binary_package(self, manifest): |
868 | 24 | """Test a package with a single binary""" | 24 | """Test a package with a single binary""" |
869 | 25 | util.create_validate_oci(util.bionic_dpkg_file, "bionic_3642", | 25 | util.create_validate_oci(util.bionic_dpkg_file, "bionic_3642", |
871 | 26 | ["--usn-number", "3642-1", "--oval-release", "bionic"], | 26 | ["--usn-number", "3642-1", "--oval-releases", "bionic"], |
872 | 27 | manifest, manifest, OVALType.USN) | 27 | manifest, manifest, OVALType.USN) |
873 | 28 | 28 | ||
874 | 29 | @pytest.mark.parametrize("manifest", | 29 | @pytest.mark.parametrize("manifest", |
875 | @@ -34,7 +34,7 @@ class TestOvalLibFunctional: | |||
876 | 34 | def test_multiple_packages_usn(self, manifest): | 34 | def test_multiple_packages_usn(self, manifest): |
877 | 35 | """Test USN with multiple source packages""" | 35 | """Test USN with multiple source packages""" |
878 | 36 | util.create_validate_oci(util.bionic_dpkg_file, "bionic_4428", | 36 | util.create_validate_oci(util.bionic_dpkg_file, "bionic_4428", |
880 | 37 | ["--usn-number", "4428-1", "--oval-release", "bionic"], | 37 | ["--usn-number", "4428-1", "--oval-releases", "bionic"], |
881 | 38 | manifest, "bionic_mock_4428", OVALType.USN) | 38 | manifest, "bionic_mock_4428", OVALType.USN) |
882 | 39 | 39 | ||
883 | 40 | @pytest.mark.parametrize("manifest,gold_file,usn", | 40 | @pytest.mark.parametrize("manifest,gold_file,usn", |
884 | @@ -68,7 +68,7 @@ class TestOvalLibFunctional: | |||
885 | 68 | def test_epoch(self, manifest, gold_file, usn): | 68 | def test_epoch(self, manifest, gold_file, usn): |
886 | 69 | """Test epochs are used correctly in vulnerability assesments""" | 69 | """Test epochs are used correctly in vulnerability assesments""" |
887 | 70 | util.create_validate_oci(util.focal_dpkg_file, "focal_{}".format(usn), | 70 | util.create_validate_oci(util.focal_dpkg_file, "focal_{}".format(usn), |
889 | 71 | ["--usn-number", usn, "--oval-release", "focal"], manifest, | 71 | ["--usn-number", usn, "--oval-releases", "focal"], manifest, |
890 | 72 | gold_file, OVALType.USN) | 72 | gold_file, OVALType.USN) |
891 | 73 | 73 | ||
892 | 74 | 74 | ||
893 | diff --git a/test/test_oval_lib_unit.py b/test/test_oval_lib_unit.py | |||
894 | index c3abf85..ab3a758 100644 | |||
895 | --- a/test/test_oval_lib_unit.py | |||
896 | +++ b/test/test_oval_lib_unit.py | |||
897 | @@ -429,8 +429,8 @@ No subscription required""" | |||
898 | 429 | assert cve_info is None | 429 | assert cve_info is None |
899 | 430 | 430 | ||
900 | 431 | def test_create_dict_from_cve_file(self): | 431 | def test_create_dict_from_cve_file(self): |
903 | 432 | cve_dir = os.environ["UCT"] | 432 | cve_dir = os.path.join(os.environ["UCT"], "active/") |
904 | 433 | dst_cve_file = os.path.join(cve_dir, "active", self.test_cve_file) | 433 | dst_cve_file = os.path.join(cve_dir, self.test_cve_file) |
905 | 434 | src_cve_file = os.path.join(rel_test_path, self.test_cve_file) | 434 | src_cve_file = os.path.join(rel_test_path, self.test_cve_file) |
906 | 435 | copyfile(src_cve_file, dst_cve_file) | 435 | copyfile(src_cve_file, dst_cve_file) |
907 | 436 | corr_cve_info = { | 436 | corr_cve_info = { |
908 | @@ -451,7 +451,7 @@ No subscription required""" | |||
909 | 451 | } | 451 | } |
910 | 452 | 452 | ||
911 | 453 | cve_info = oval_lib.OvalGeneratorUSN.get_cve_info_from_file( | 453 | cve_info = oval_lib.OvalGeneratorUSN.get_cve_info_from_file( |
913 | 454 | self.oval_gen_mock, self.test_cve_file, cve_dir) | 454 | self.oval_gen_mock, self.test_cve_file, [cve_dir]) |
914 | 455 | 455 | ||
915 | 456 | try: | 456 | try: |
916 | 457 | assert cve_info == corr_cve_info | 457 | assert cve_info == corr_cve_info |
917 | diff --git a/test/test_utils.py b/test/test_utils.py | |||
918 | index 682e45a..d62a842 100644 | |||
919 | --- a/test/test_utils.py | |||
920 | +++ b/test/test_utils.py | |||
921 | @@ -6,9 +6,9 @@ import subprocess | |||
922 | 6 | from enum import Enum | 6 | from enum import Enum |
923 | 7 | 7 | ||
924 | 8 | class OVALType(Enum): | 8 | class OVALType(Enum): |
928 | 9 | USN = '--usn-oval' | 9 | USN = '--type=usn' |
929 | 10 | CVE = '' | 10 | CVE = '--type=cve' |
930 | 11 | PKG = '--pkg-oval' | 11 | PKG = '--type=pkg' |
931 | 12 | 12 | ||
932 | 13 | class TestUtilities: | 13 | class TestUtilities: |
933 | 14 | cwd = os.getcwd() | 14 | cwd = os.getcwd() |
LGTM, no changes in the OVAL output before and after this PR. Thanks!