def test_download_cache_load_expired(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) monkeypatch.setattr(CachedFile, "is_expired", True) url = "file://%s" % os.path.abspath("./tests/assets/1.json") write_test_file_cache(tmpdir) shutil.copy("./tests/assets/1.json", tmpdir.join("98")) udc = USTDownloadCache(null_logger, tmpdir) mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc.get_data_from_url(url) with open(tmpdir.join("file_cache.json")) as f: cache_contents = json.load(f) expected_cache_contents = { url: { "url": url, "path": str(tmpdir.join("99")), "timestamp": 1591401600, "ttl": 60, } } assert cache_contents == expected_cache_contents
def test_download_creates_file_cache(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) url = "file://%s" % os.path.abspath("./tests/assets/1.json") mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc = USTDownloadCache(null_logger, tmpdir) udc.get_data_from_url(url) assert os.path.exists(tmpdir.join("file_cache.json"))
def test_gzip_error(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) monkeypatch.setattr(gzip, "open", raise_test_exception) url = "file://%s" % os.path.abspath("./tests/assets/4.json.gz") with pytest.raises(GZExtractionError): udc = USTDownloadCache(null_logger, tmpdir) mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc.get_data_from_url(url)
def test_download_error(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) monkeypatch.setattr(requests, "get", raise_test_exception) url = "file://%s" % os.path.abspath("./tests/assets/1.json") with pytest.raises(DownloadError): udc = USTDownloadCache(null_logger, tmpdir) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: raise_test_exception) udc.get_data_from_url(url)
def test_download_get_cache_metadata(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) url = "file://%s" % os.path.abspath("./tests/assets/1.json") mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc = USTDownloadCache(null_logger, tmpdir) metadata = udc.get_cache_metadata_from_url(url) assert metadata["version"] == "1.0" assert metadata["timestamp"] == 1591401600 assert metadata["ttl"] == 60
def test_download_gzip(null_logger, tmpdir, monkeypatch, uuid4): url = "file://%s" % os.path.abspath("./tests/assets/4.json.gz") udc = USTDownloadCache(null_logger, tmpdir) mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) data = udc.get_data_from_url(url) assert data["a"] == "I" assert data["b"] == "II" assert data["c"] == "III"
def test_download_missing_metadata(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) url = "file://%s" % os.path.abspath("./tests/assets/3.json") with pytest.raises(Exception): udc = USTDownloadCache(null_logger, tmpdir) mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc.get_data_from_url(url) assert not os.path.exists(tmpdir.join("99"))
def test_download_get_data(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) url = "file://%s" % os.path.abspath("./tests/assets/1.json") mr = MockResponse("", 200, url=url) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc = USTDownloadCache(null_logger, tmpdir) data = udc.get_data_from_url(url) assert data["a"] == 1 assert data["b"] == 2 assert data["c"] == 3
def test_download_404(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) mr = MockResponse("", 404) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) url = "file://%s" % os.path.abspath("./tests/assets/1.json") with pytest.raises(DownloadError) as de: udc = USTDownloadCache(null_logger, tmpdir) udc.get_data_from_url(url) assert "404" in str(de.value)
def test_download_cache_load_failed_json_error(null_logger, tmpdir, monkeypatch, uuid4): write_test_file_cache(tmpdir) shutil.copy("./tests/assets/malformed_json_file_cache.json", tmpdir.join("file_cache.json")) with pytest.raises(FileCacheLoadError) as fcle: USTDownloadCache(null_logger, tmpdir) assert "File contains malformed JSON" in str(fcle.value)
def main(): global LOGGER args = parse_args() # Configure debug logging as early as possible LOGGER = set_output_verbosity(args) local_sysinfo = LocalSysInfo(LOGGER) try: opt = Options(args) except (ArgumentError, ValueError) as err: error_exit("Invalid option or argument: %s" % err, const.CLI_ERROR_RETURN_CODE) error_exit_code = (const.NAGIOS_UNKNOWN_RETURN_CODE if opt.nagios_mode else const.ERROR_RETURN_CODE) try: try: target_sysinfo = TargetSysInfo(opt, local_sysinfo) log_config_options(opt) log_local_system_info(local_sysinfo, opt.manifest_mode) log_target_system_info(target_sysinfo) except (FileNotFoundError, PermissionError) as err: error_exit("Failed to determine the correct Ubuntu codename: %s" % err) except DistribIDError as di: error_exit( "Invalid linux distribution detected, CVEScan must be run on Ubuntu: %s" % di) except PkgCountError as pke: error_exit("Failed to determine the local package count: %s" % pke) output_formatter = load_output_formatter(opt) download_cache = USTDownloadCache(LOGGER) uct_data = load_uct_data(opt, download_cache, target_sysinfo) cve_scanner = CVEScanner(LOGGER) scan_results = cve_scanner.scan(target_sysinfo.codename, uct_data, target_sysinfo.installed_pkgs) (results, return_code) = output_formatter.format_output(scan_results, target_sysinfo) except Exception as ex: error_exit( "An unexpected error occurred while running CVEScan: %s" % ex, error_exit_code, ) LOGGER.info(results) sys.exit(return_code)
def test_download_cache_load_permission_denied_error(null_logger, tmpdir, monkeypatch, uuid4): write_test_file_cache(tmpdir) cache_file = tmpdir.join("file_cache.json") shutil.copy("./tests/assets/malformed_json_file_cache.json", cache_file) os.chmod(cache_file, 0o000) with pytest.raises(FileCacheLoadError) as fcle: USTDownloadCache(null_logger, tmpdir) assert "Permission denied" in str(fcle.value)
def test_download_creates_file_cache_contents_2(null_logger, tmpdir, monkeypatch, uuid4): monkeypatch.setattr(uuid, "uuid4", uuid4.get) url1 = "file://%s" % os.path.abspath("./tests/assets/1.json") url2 = "file://%s" % os.path.abspath("./tests/assets/2.json.bz2") udc = USTDownloadCache(null_logger, tmpdir) mr = MockResponse("", 200, url=url1) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc.get_data_from_url(url1) mr = MockResponse("", 200, url=url2) monkeypatch.setattr(requests, "get", lambda *args, **kwargs: mr) udc.get_data_from_url(url2) with open(tmpdir.join("file_cache.json")) as f: cache_contents = json.load(f) expected_cache_contents = { url1: { "url": url1, "path": str(tmpdir.join("99")), "timestamp": 1591401600, "ttl": 60, }, url2: { "url": url2, "path": str(tmpdir.join("100")), "timestamp": 1591402600, "ttl": 3600, }, } assert cache_contents == expected_cache_contents
def main(): args = parse_args() try: opt = Options(args) except (ArgumentError, ValueError) as err: error_exit(f"Invalid option or argument -- {err}", const.CLI_ERROR_RETURN_CODE) error_exit.default_code = (const.NAGIOS_UNKNOWN_RETURN_CODE if opt.nagios_mode else const.ERROR_RETURN_CODE) logger = set_output_verbosity(opt) try: local_sysinfo, target_sysinfo = get_sysinfo(opt, logger) except (FileNotFoundError, PermissionError) as err: error_exit(f"Failed to determine the correct Ubuntu codename -- {err}") except DistribIDError as di: error_exit( f"Invalid linux distribution detected, CVEScan must be run on Ubuntu -- {di}" ) except PkgCountError as pke: error_exit(f"Failed to determine the local package count -- {pke}") download_cache = USTDownloadCache(logger) uct_data = load_uct_data(opt, download_cache, target_sysinfo) scan_results = run_scan(target_sysinfo, uct_data, logger) output_formatter = load_output_formatter(opt, logger) (formatted_output, return_code) = output_formatter.format_output(scan_results, target_sysinfo) try: output_logger = get_output_logger(opt, logger) output(output_logger, formatted_output, return_code) sys.exit(return_code) except socket.gaierror as se: error_exit( f"Failed to send syslog output to {opt.syslog_host}:{opt.syslog_port} -- {se}" )
def test_set_cache_dir_constructor(null_logger, tmpdir): udc = USTDownloadCache(null_logger, cache_dir=tmpdir.join("my_ust_cache")) assert udc.cache_dir == tmpdir.join("my_ust_cache")
def test_set_cache_home(null_logger, tmpdir, monkeypatch): monkeypatch.setenv("HOME", str(tmpdir.join("HOME_TEST"))) udc = USTDownloadCache(null_logger) assert udc.cache_dir == tmpdir.join("HOME_TEST").join(".ust_cache")
def test_create_cache_dir_file_exists(null_logger, tmpdir, monkeypatch): tmpdir.join(".ust_cache").write("") with pytest.raises(FileExistsError): USTDownloadCache(null_logger, tmpdir.join(".ust_cache"))
def test_create_cache_dir(null_logger, tmpdir, monkeypatch): USTDownloadCache(null_logger, tmpdir.join(".ust_cache")) assert os.path.isdir(tmpdir.join(".ust_cache"))
def test_set_cache_snap(null_logger, tmpdir, monkeypatch): monkeypatch.setenv("SNAP_USER_COMMON", str(tmpdir.join("SNAP_TEST"))) udc = USTDownloadCache(null_logger) assert udc.cache_dir == tmpdir.join("SNAP_TEST").join(".ust_cache")