Skip to content

Commit 08580bd

Browse files
authored
Merge branch 'main' into newcontrib
2 parents ea2bcfc + 161aeec commit 08580bd

File tree

5 files changed

+69
-12
lines changed

5 files changed

+69
-12
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Usage:
9090
-V, --version show program's version number and exit
9191
--disable-version-check
9292
skips checking for a new version
93+
--offline operate in offline mode
9394

9495
CVE Data Download:
9596
-n {json,api}, --nvd {json,api}
@@ -168,6 +169,12 @@ in the terminal and provide it as an input by running `cve-bin-tool -L pkg-list`
168169
You can use `--config` option to provide configuration file for the tool. You can still override options specified in config file with command line arguments. See our sample config files in the
169170
[test/config](https://github.com/intel/cve-bin-tool/blob/main/test/config/)
170171

172+
Specifying the `--offline` option when running a scan ensures that cve-bin-tool doesn't attempt to download the latest database files or to check for a newer version of the tool.
173+
174+
The 0.3.1 release is intended to be the last release to officially support
175+
python 2.7; please switch to python 3.6+ for future releases and to use the
176+
development tree. You can check [our CI configuration](https://github.com/intel/cve-bin-tool/blob/main/.github/workflows/pythonapp.yml) to see what versions of python we're explicitly testing.
177+
171178
## Using CVE Binary Tool in Github Actions
172179

173180
If you want to integrate cve-bin-tool as a part of your github action pipeline.

cve_bin_tool/cli.py

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
"""
1414

1515
import argparse
16+
import importlib.util
1617
import logging
1718
import os
1819
import platform
1920
import sys
2021
import textwrap
22+
import time
2123
from collections import ChainMap
2224
from typing import Dict
2325

@@ -218,6 +220,11 @@ def main(argv=None):
218220
action="store_true",
219221
help="skips checking for a new version",
220222
)
223+
parser.add_argument(
224+
"--offline",
225+
action="store_true",
226+
help="operate in offline mode",
227+
)
221228

222229
merge_report_group = parser.add_argument_group(
223230
"Merge Report", "Arguments related to Intermediate and Merged Reports"
@@ -302,6 +309,7 @@ def main(argv=None):
302309
"affected_versions": 0,
303310
"sbom": "spdx",
304311
"sbom_file": "",
312+
"offline": False,
305313
}
306314

307315
with ErrorHandler(mode=ErrorMode.NoTrace):
@@ -348,6 +356,24 @@ def main(argv=None):
348356
if int(args["cvss"]) > 0:
349357
score = int(args["cvss"])
350358

359+
# Offline processing
360+
if args["offline"]:
361+
# Override version check and database update arguments
362+
version_check = True
363+
db_update = "never"
364+
else:
365+
version_check = args["disable_version_check"]
366+
db_update = args["update"]
367+
368+
# Check for PDF support
369+
output_format = args["format"]
370+
if output_format == "pdf" and importlib.util.find_spec("reportlab") is None:
371+
LOGGER.info("PDF output not available. Default to console.")
372+
LOGGER.info(
373+
"If you want to produce PDF output, please install reportlab using pip install reportlab"
374+
)
375+
output_format = "console"
376+
351377
merged_reports = None
352378
if args["merge"]:
353379
LOGGER.info(
@@ -370,12 +396,10 @@ def main(argv=None):
370396
# Database update related settings
371397
# Connect to the database
372398
cvedb_orig = CVEDB(
373-
version_check=not args["disable_version_check"],
399+
version_check=not version_check,
374400
error_mode=error_mode,
375401
nvd_type=args["nvd"],
376-
incremental_update=True
377-
if args["update"] == "latest" and args["nvd"]
378-
else False,
402+
incremental_update=True if db_update == "latest" and args["nvd"] else False,
379403
)
380404

381405
# if OLD_CACHE_DIR (from cvedb.py) exists, print warning
@@ -384,15 +408,23 @@ def main(argv=None):
384408
f"Obsolete cache dir {OLD_CACHE_DIR} is no longer needed and can be removed."
385409
)
386410

411+
# Check database exists if operating in offline mode.
412+
if args["offline"] and not cvedb_orig.check_db_exists():
413+
LOGGER.critical("Database does not exist.")
414+
LOGGER.info(
415+
"Consult the documentation at https://cve-bin-tool.readthedocs.io/en/latest/how_to_guides/offline.html to find out how to setup offline operation."
416+
)
417+
return -1
418+
387419
# Clear data if -u now is set
388-
if args["update"] == "now":
420+
if db_update == "now":
389421
cvedb_orig.clear_cached_data()
390422

391-
if args["update"] == "latest":
423+
if db_update == "latest":
392424
cvedb_orig.refresh_cache_and_update_db()
393425

394426
# update db if needed
395-
if args["update"] != "never":
427+
if db_update != "never":
396428
cvedb_orig.get_cvelist_if_stale()
397429
else:
398430
if args["nvd"] == "json":
@@ -407,6 +439,12 @@ def main(argv=None):
407439
with ErrorHandler(mode=error_mode, logger=LOGGER):
408440
raise CVEDataMissing("No data in CVE Database")
409441

442+
# Report time of last database update
443+
db_date = time.strftime(
444+
"%d %B %Y at %H:%M:%S", time.localtime(cvedb_orig.get_db_update_date())
445+
)
446+
LOGGER.info(f"CVE database last updated on {db_date}")
447+
410448
cvedb_orig.remove_cache_backup()
411449

412450
# Input validation
@@ -545,7 +583,7 @@ def main(argv=None):
545583
)
546584

547585
if not args["quiet"]:
548-
output.output_file(args["format"])
586+
output.output_file(output_format)
549587
if args["backport_fix"] or args["available_fix"]:
550588
distro_info = args["backport_fix"] or args["available_fix"]
551589
is_backport = True if args["backport_fix"] else False

cve_bin_tool/cvedb.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ async def nist_fetch_using_api(self):
122122
nvd_api.session = None
123123
return nvd_api.all_cve_entries
124124

125+
def check_db_exists(self):
126+
return os.path.isfile(self.dbpath)
127+
125128
def get_db_update_date(self):
126129
# last time when CVE data was updated
127130
self.time_of_last_update = datetime.datetime.fromtimestamp(

doc/how_to_guides/offline.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ NOTE The tool will error with InsufficientArgs because no directory was specifie
1515
The way of transfer depends on the environment. The files to be transferred are in "~/.cache/cve-bin-tool"
1616

1717
## Import the vulnerability database file on the offline system
18-
The vulnerability database should be copied into ~/.cache/cve-bin-tool
18+
The vulnerability database should be copied into ~/.cache/cve-bin-tool.
1919

20-
## Run cve-bin-tool with --update never and --disable-version-check options
21-
In an offline environment, when running a scan specify `--update never` so that cve-bin-tool doesn't attempt to download the latest database files and `--disable-version-check` so that the cve-bin-tool doesn't attempt to check for a newer version of the tool.
20+
The cve-bin-tool will fail to operate in offline mode if a vulnerability database is not present on the system.
21+
22+
## Run cve-bin-tool with --offline option
23+
In an offline environment, specify the `--offline` option when running a scan so that cve-bin-tool doesn't attempt to download the latest database files or check for a newer version of the tool.
24+
The `--offline` option is equivalent to specifying `--update never` and `--disable-version-check` options.
2225

2326
## Maintenance Updates
24-
In an offline environment, it is important to update the vulnerability database on a regular basis as often as you feel appropriate, so that the scanner can continue to detect recently-identified vulnerabilities. If any changes to CVE data is required (e.g. to remove false positives), you might also want to create and copy over a triage data file for usage.
27+
In an offline environment, it is important to update the vulnerability database on a regular basis as often as you feel appropriate, so that the scanner can continue to detect recently-identified vulnerabilities. If any changes to CVE data is required (e.g. to remove false positives), you might also want to create and copy over a triage data file for usage. The time of the latest database update is reported whenever a scan is performed.
2528

2629
It is important to periodically check if the cve-bin-tool has also been updated as this check cannot be performed within an offline environment.

test/test_output_engine.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
CVE-bin-tool OutputEngine tests
66
"""
77
import csv
8+
import importlib.util
89
import json
910
import logging
1011
import os
@@ -470,6 +471,11 @@ def test_output_csv(self):
470471
expected_value = [dict(x) for x in reader]
471472
self.assertEqual(expected_value, self.FORMATTED_OUTPUT)
472473

474+
@unittest.skipUnless(
475+
importlib.util.find_spec("reportlab") is not None
476+
and importlib.util.find_spec("pdftotext") is not None,
477+
"Skipping PDF tests. Please install reportlab and pdftotext to run these tests.",
478+
)
473479
def test_output_pdf(self):
474480
"""Test formatting output as PDF"""
475481
output_pdf(self.MOCK_PDF_OUTPUT, False, 1, "cve_test.pdf", False)

0 commit comments

Comments
 (0)