1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
# SPDX-FileCopyrightText: 2021-2024 Greenbone AG
#
# SPDX-License-Identifier: AGPL-3.0-or-later
import json
import unittest
from pathlib import Path
from typing import List, Optional, Tuple
from notus.scanner.loader.gpg_sha_verifier import VerificationResult
from notus.scanner.loader.json import JSONAdvisoriesLoader
from notus.scanner.messages.message import Message
from notus.scanner.messages.start import ScanStartMessage
from notus.scanner.messaging.publisher import Publisher
from notus.scanner.scanner import NotusScanner
_here = Path(__file__).parent
class FakePublisher(Publisher):
def __init__(self):
self.results = []
def publish(self, message: Message) -> None:
serialized = message.serialize()
values = str(serialized.get("value", "")).split("\n")
for value in values:
if value.find("Installed version:") >= 0:
installed = value.split(":")[1].strip()
self.results.append(installed)
class VerifierTestCase(unittest.TestCase):
"""
VerifierTestCase loads a notus advisory for FakeSpecifierOS
and iterates through defined fixed packages and their specifier
to generate and test them.
"""
def per_symbol(
self, name: str, verifier: Optional[str]
) -> Tuple[List[str], List[str]]:
"""
returns not_in_result and in result
"""
greater = lambda: name.replace( # pylint: disable=unnecessary-lambda-assignment # noqa: E731
"15", "16"
)
smaller = lambda: name.replace( # pylint: disable=unnecessary-lambda-assignment # noqa: E731
"15", "14"
) # pylint: disable=unnecessary-lambda-assignment
if not verifier:
return [greater(), name], [smaller()]
if verifier == ">":
return [greater()], [name, smaller()]
if verifier == ">=":
return [greater(), name], [smaller()]
if verifier == "<":
return [smaller()], [name, greater()]
if verifier == "<=":
return [smaller(), name], [greater()]
return [name], [smaller(), greater()]
def generate_test_cases(self):
jdict = json.loads((_here / "fakespecifier_os.notus").read_bytes())
fixed_packages = (
f.get("fixed_packages", []) for f in jdict.get("advisories", {})
)
cases = (
(fp.get("full_name"), fp.get("specifier"))
for fps in fixed_packages
for fp in fps
)
# cases that should not appear in result
not_in = []
# cases that should appear in result
is_in = []
for case in cases:
c_not_in, c_is_in = self.per_symbol(*case)
not_in = not_in + c_not_in
is_in = is_in + c_is_in
# packagelist is both combined
return not_in + is_in, not_in, is_in
def test_verifier(self):
loader = JSONAdvisoriesLoader(
advisories_directory_path=_here,
verify=lambda _: VerificationResult.SUCCESS,
)
publisher = FakePublisher()
scanner = NotusScanner(loader, publisher)
pkg_list, not_in_results, in_results = self.generate_test_cases()
msg = ScanStartMessage(
scan_id="scanus praktikus",
os_release="FakeSpecifier OS",
host_ip="127.0.0.2",
host_name="localhorst",
package_list=pkg_list,
)
scanner.run_scan(msg)
results = set(publisher.results)
self.assertEqual(len(results), len(publisher.results))
self.assertEqual(
set(),
results.intersection(not_in_results),
)
self.assertEqual(set(in_results), results.intersection(in_results))
|