예제 #1
0
def test_csv():
    sr = filter_scan_results_by_cve_ids(
        ["CVE-2020-1000", "CVE-2020-1001", "CVE-2020-1005"])

    opt = MockOpt()
    opt.priority = "all"
    opt.unresolved = True

    formatter = CSVOutputFormatter(opt, null_logger())
    (results_msg, return_code) = formatter.format_output(sr, MockSysInfo())

    expected_csv_results = "CVE ID,PRIORITY,PACKAGE,FIXED_VERSION,REPOSITORY"
    expected_csv_results += "\nCVE-2020-1000,low,pkg3,,"
    expected_csv_results += (
        "\nCVE-2020-1001,high,pkg1,1:1.2.3-4+deb9u2ubuntu0.2,Ubuntu Archive")
    expected_csv_results += (
        "\nCVE-2020-1001,high,pkg2,1:1.2.3-4+deb9u2ubuntu0.2,Ubuntu Archive")
    expected_csv_results += ("\nCVE-2020-1005,low,pkg1,1:1.2.3-4+deb9u3,%s" %
                             const.UA_APPS)
    expected_csv_results += ("\nCVE-2020-1005,low,pkg2,1:1.2.3-4+deb9u3,%s" %
                             const.UA_APPS)
    expected_csv_results += ("\nCVE-2020-1005,low,pkg3,10.2.3-2ubuntu0.1,%s" %
                             const.UA_INFRA)

    assert results_msg == expected_csv_results
def test_no_patch_available_infra_experimental(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1003"])
    sr.append(ScanResult("CVE-2020-1000", "low", "pkg3", "1.2.3-4", const.UA_INFRA),)
    cve_output_formatter.opt.experimental_mode = False
    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())

    assert msg == "Vulnerable to CVE-2020-1000. There is no fix available, yet."
    assert rc == 3
예제 #3
0
def test_no_tty_no_color(monkeypatch, table_only_cli_output_formatter):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: False)
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001"])

    (results_msg, return_code) = table_only_cli_output_formatter.format_output(
        sr, MockSysInfo())

    assert "\u001b" not in results_msg
예제 #4
0
def test_summary_priority_all(monkeypatch, summary_only_cli_output_formatter):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: False)
    cof = summary_only_cli_output_formatter

    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001"])

    (results_msg, return_code) = cof.format_output(sr, MockSysInfo())

    assert re.search(r"CVE Priority\s+All", results_msg)
def test_vulnerable_patch_available_infra(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1003"])
    sr.append(ScanResult("CVE-2020-1000", "low", "pkg3", "1.2.3-4", const.UA_INFRA),)
    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())

    assert (
        msg
        == f"Vulnerable to CVE-2020-1000, but fixes are available from {const.UA_INFRA}."
    )
예제 #6
0
def test_ua_infra_unknown_text(monkeypatch, table_only_cli_output_formatter):
    sysinfo = MockSysInfo()
    sysinfo.esm_infra_enabled = None

    sr = filter_scan_results_by_cve_ids("CVE-2020-1010")

    (results_msg,
     return_code) = table_only_cli_output_formatter.format_output(sr, sysinfo)

    assert "(disabled)" not in results_msg
예제 #7
0
def test_ua_apps_disabled_text(monkeypatch, table_only_cli_output_formatter):
    sysinfo = MockSysInfo()
    sysinfo.esm_apps_enabled = False
    sysinfo.esm_infra_enabled = True

    sr = filter_scan_results_by_cve_ids("CVE-2020-1009")

    (results_msg,
     return_code) = table_only_cli_output_formatter.format_output(sr, sysinfo)

    assert "(disabled)" in results_msg
def test_always_show_links():
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1004", "CVE-2020-1005"])
    opt = MockOpt()
    opt.unresolved = True
    opt.show_links = False
    formatter = JSONOutputFormatter(opt, null_logger())

    (results_msg, return_code) = formatter.format_output(sr, MockSysInfo())

    assert const.UCT_URL % "CVE-2020-1004" in results_msg
    assert const.UCT_URL % "CVE-2020-1005" in results_msg
def test_vulnerable_patch_available_repository(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1003"])
    sr.append(
        ScanResult("CVE-2020-1000", "low", "pkg3", "1.2.3-4", const.UBUNTU_ARCHIVE),
    )
    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())

    expected_msg = (
        "Vulnerable to CVE-2020-1000, but fixes are available from "
        "the Ubuntu Archive."
    )

    assert msg == expected_msg
    assert rc == 4
def run_json_format_test(indent):
    sr = filter_scan_results_by_cve_ids(
        ["CVE-2020-1000", "CVE-2020-1001", "CVE-2020-1005"])

    opt = MockOpt()
    opt.priority = "all"
    opt.unresolved = True

    formatter = JSONOutputFormatter(opt, null_logger(), indent=indent)

    (results_msg, return_code) = formatter.format_output(sr, MockSysInfo())

    expected_output = json.dumps(sample_output, indent=indent, sort_keys=False)

    assert results_msg == expected_output
예제 #11
0
def test_no_results_no_header(monkeypatch):
    header_regex = r"CVE ID\s+PRIORITY\s+PACKAGE\s+FIXED VERSION\s+REPOSITORY"

    monkeypatch.setattr(sys.stdout, "isatty", lambda: False)
    cof = CLIOutputFormatter(MockOpt(), null_logger())
    sysinfo = MockSysInfo()

    cof.opt.experimental_mode = True
    cof.opt.unresolved = False

    sr = filter_scan_results_by_cve_ids(["CVE-2020-1003"])

    (results_msg, return_code) = cof.format_output(sr, sysinfo)

    assert not re.search(header_regex, results_msg)
예제 #12
0
def run_color_test(monkeypatch, table_only_cli_output_formatter, sysinfo,
                   cve_id, color_code):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: True)

    if color_code is None:
        expected_color = ""
    else:
        expected_color = "38;5;%dm" % color_code

    table_only_cli_output_formatter.opt.unresolved = True
    sr = filter_scan_results_by_cve_ids([cve_id])

    (results_msg,
     return_code) = table_only_cli_output_formatter.format_output(sr, sysinfo)

    assert expected_color in results_msg
def test_vulnerable_patch_available_apps_infra(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1003"])
    sr = sr + [
        ScanResult("CVE-2020-1000", "low", "pkg4", "1.2.3-4", const.UA_INFRA),
        ScanResult("CVE-2020-1000", "low", "pkg5", "1.2.3-4", const.UA_APPS),
    ]

    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())

    expected_msg = (
        "Vulnerable to CVE-2020-1000, but fixes are available from "
        f"{const.UA_APPS} and {const.UA_INFRA}."
    )

    assert msg == expected_msg
    assert rc == 4
def test_vulnerable_patch_available_infra_repository_duplicates(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1003"])
    sr = sr + [
        ScanResult("CVE-2020-1000", "low", "pkg3", "1.2.3-4", const.UBUNTU_ARCHIVE),
        ScanResult("CVE-2020-1000", "low", "pkg5", "1.2.3-4", const.UA_INFRA),
        ScanResult("CVE-2020-1000", "low", "pkg6", "1.2.3-4", const.UA_INFRA),
    ]

    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())
    expected_msg = (
        "Vulnerable to CVE-2020-1000, but fixes are available from "
        f"{const.UA_INFRA} and the Ubuntu Archive."
    )

    assert msg == expected_msg
    assert rc == 4
예제 #15
0
def test_suggestions_empty_no_experimental_infra_enabled(
        monkeypatch, suggestions_only_cli_output_formatter):
    cof = suggestions_only_cli_output_formatter

    cof.opt.priority = const.LOW
    cof.opt.experimental_mode = False

    sysinfo = MockSysInfo()
    sysinfo.esm_apps_enabled = False
    sysinfo.esm_infra_enabled = True

    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1010"])

    (results_msg, return_code) = cof.format_output(sr, sysinfo)

    assert (
        "additional security patch(es) are available if ESM for Infrastructure is enabled with\nUbuntu Advantage."
        not in results_msg)
예제 #16
0
def test_summary_experimental_filter(monkeypatch,
                                     summary_only_cli_output_formatter):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: False)
    cof = summary_only_cli_output_formatter
    sysinfo = MockSysInfo()
    sysinfo.esm_apps_enabled = False
    sysinfo.esm_infra_enabled = True

    cof.opt.experimental_mode = False

    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001"])

    (results_msg, return_code) = cof.format_output(sr, sysinfo)

    assert "Vulnerabilities Fixable by ESM" not in results_msg
    # Disable this test for now
    # assert "UA Apps Enabled" not in results_msg
    # assert "UA Infra Enabled" not in results_msg
    assert "Available Fixes Not Applied" not in results_msg
예제 #17
0
def run_esm_color_code_test(monkeypatch, output_formatter, sysinfo,
                            repository_color_code, yn):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: True)

    sr = filter_scan_results_by_cve_ids(["CVE-2020-1005"])

    (results_msg, return_code) = output_formatter.format_output(sr, sysinfo)

    if yn == "Unknown":
        fixable_color_code = ""
    else:
        fixable_color_code = r"\u001b\[38;5;%dm" % repository_color_code
    assert re.search(
        r"Vulnerabilities Fixable by %s\s+%s2" %
        (const.UA_APPS, fixable_color_code),
        results_msg,
    )
    assert re.search(
        r"Vulnerabilities Fixable by %s\s+%s1" %
        (const.UA_INFRA, fixable_color_code),
        results_msg,
    )
예제 #18
0
def run_fixes_not_applied_color_code_test(
    monkeypatch,
    output_formatter,
    sysinfo,
    repository_color_code,
    num_fixes,
    unknown=False,
):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: True)

    sr = filter_scan_results_by_cve_ids(["CVE-2020-1005"])

    (results_msg, return_code) = output_formatter.format_output(sr, sysinfo)

    fixable_color_code = ""
    if num_fixes != 0 and not unknown:
        fixable_color_code = r"\u001b\[38;5;%dm" % repository_color_code
    assert re.search(
        r"Available Fixes Not Applied by `apt-get upgrade`\s+%s%d" %
        (fixable_color_code, num_fixes),
        results_msg,
    )
예제 #19
0
def test_summary_nounresolved(monkeypatch, summary_only_cli_output_formatter):
    monkeypatch.setattr(sys.stdout, "isatty", lambda: False)
    cof = summary_only_cli_output_formatter

    cof.opt.priority = const.LOW
    cof.opt.unresolved = False

    sysinfo = MockSysInfo()
    sysinfo.esm_apps_enabled = False
    sysinfo.esm_infra_enabled = False

    sr = filter_scan_results_by_cve_ids([
        "CVE-2020-1001",
        "CVE-2020-1002",
        "CVE-2020-1003",
        "CVE-2020-1005",
        "CVE-2020-1009",
        "CVE-2020-1010",
    ])

    (results_msg, return_code) = cof.format_output(sr, sysinfo)

    assert re.search(r"Ubuntu Release\s+bionic", results_msg)
    assert re.search(r"Installed Packages\s+100", results_msg)
    assert re.search(r"CVE Priority\s+low or higher", results_msg)
    assert re.search(r"Unique Packages Fixable by Patching\s+6", results_msg)
    assert re.search(r"Unique CVEs Fixable by Patching\s+5", results_msg)
    assert re.search(r"Vulnerabilities Fixable by Patching\s+10", results_msg)
    assert re.search(r"Vulnerabilities Fixable by %s\s+6" % const.UA_APPS,
                     results_msg)
    assert re.search(r"Vulnerabilities Fixable by %s\s+2" % const.UA_INFRA,
                     results_msg)
    # Disabling for now
    # assert re.search(r"UA Apps Enabled\s+No", results_msg)
    # assert re.search(r"UA Infra Enabled\s+No", results_msg)
    assert re.search(r"Fixes Available by `apt-get upgrade`\s+2", results_msg)
    assert re.search(r"Available Fixes Not Applied by `apt-get upgrade`\s+8",
                     results_msg)
def test_vulnerable_no_patch(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1000", "CVE-2020-1003"])
    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())

    assert msg == "Vulnerable to CVE-2020-1000. There is no fix available, yet."
    assert rc == 3
def test_json_format():
    sr = filter_scan_results_by_cve_ids(
        ["CVE-2020-1000", "CVE-2020-1001", "CVE-2020-1005"])

    opt = MockOpt()
    opt.priority = "all"
    opt.unresolved = True

    formatter = JSONOutputFormatter(opt, null_logger())

    (results_msg, return_code) = formatter.format_output(sr, MockSysInfo())

    expected_output = json.dumps(
        {
            "summary": {
                "ubuntu_release": "bionic",
                "num_installed_packages": 100,
                "num_cves": 2,
                "num_affected_packages": 3,
                "num_patchable_vulnerabilities": 5,
            },
            "cves": {
                "CVE-2020-1000": {
                    "url":
                    "https://people.canonical.com/~ubuntu-security/cve/CVE-2020-1000",
                    "packages": {
                        "pkg3": {
                            "priority": "low",
                            "fixed_version": "",
                            "repository": "",
                        }
                    },
                },
                "CVE-2020-1001": {
                    "url":
                    "https://people.canonical.com/~ubuntu-security/cve/CVE-2020-1001",
                    "packages": {
                        "pkg1": {
                            "priority": "high",
                            "fixed_version": "1:1.2.3-4+deb9u2ubuntu0.2",
                            "repository": "Ubuntu Archive",
                        },
                        "pkg2": {
                            "priority": "high",
                            "fixed_version": "1:1.2.3-4+deb9u2ubuntu0.2",
                            "repository": "Ubuntu Archive",
                        },
                    },
                },
                "CVE-2020-1005": {
                    "url":
                    "https://people.canonical.com/~ubuntu-security/cve/CVE-2020-1005",
                    "packages": {
                        "pkg1": {
                            "priority": "low",
                            "fixed_version": "1:1.2.3-4+deb9u3",
                            "repository": const.UA_APPS,
                        },
                        "pkg2": {
                            "priority": "low",
                            "fixed_version": "1:1.2.3-4+deb9u3",
                            "repository": const.UA_APPS,
                        },
                        "pkg3": {
                            "priority": "low",
                            "fixed_version": "10.2.3-2ubuntu0.1",
                            "repository": const.UA_INFRA,
                        },
                    },
                },
            },
        },
        indent=4,
        sort_keys=False,
    )

    assert results_msg == expected_output
def test_not_vulnerable(cve_output_formatter):
    sr = filter_scan_results_by_cve_ids(["CVE-2020-1001", "CVE-2020-1003"])
    msg, rc = cve_output_formatter.format_output(sr, MockSysInfo())

    assert msg == "Not affected by CVE-2020-1000."
    assert rc == 0