- SSH scanning via ssh-audit (KEX, encryption, MAC, host keys) - BSI TR-02102-4 and IANA compliance validation for SSH - CSV/Markdown/reST reports for SSH results - Unified compliance schema and database views - Code optimization: modular query/writer architecture
131 lines
5.5 KiB
Python
131 lines
5.5 KiB
Python
"""Tests for query functions that use direct SQL queries."""
|
|
|
|
from src.sslysze_scan.reporter.query import (
|
|
fetch_scan_data,
|
|
fetch_scan_metadata,
|
|
fetch_scans,
|
|
)
|
|
|
|
|
|
class TestQueryFunctions:
|
|
"""Tests for query functions that use direct SQL queries."""
|
|
|
|
def test_list_scans(self, test_db_path: str) -> None:
|
|
"""Test the list_scans function."""
|
|
scans = fetch_scans(test_db_path)
|
|
|
|
# Should return a list
|
|
assert isinstance(scans, list)
|
|
|
|
# If there are scans in the DB, they should have expected structure
|
|
for scan in scans:
|
|
assert "scan_id" in scan
|
|
assert "timestamp" in scan
|
|
assert "hostname" in scan
|
|
assert "ports" in scan
|
|
assert "duration" in scan
|
|
|
|
def test_get_scan_metadata(self, test_db_path: str) -> None:
|
|
"""Test the fetch_scan_metadata function."""
|
|
# Get available scans to pick a valid scan_id
|
|
scans = fetch_scans(test_db_path)
|
|
if scans:
|
|
scan_id = scans[0]["scan_id"]
|
|
metadata = fetch_scan_metadata(test_db_path, scan_id)
|
|
|
|
assert metadata is not None
|
|
assert "scan_id" in metadata
|
|
assert "timestamp" in metadata
|
|
assert "hostname" in metadata
|
|
assert "ports" in metadata
|
|
assert "duration" in metadata
|
|
assert "fqdn" in metadata
|
|
assert isinstance(metadata["ports"], list)
|
|
|
|
def test_get_scan_data_structure(self, test_db_path: str) -> None:
|
|
"""Test the structure returned by fetch_scan_data function."""
|
|
# Get available scans to pick a valid scan_id
|
|
scans = fetch_scans(test_db_path)
|
|
if scans:
|
|
scan_id = scans[0]["scan_id"]
|
|
data = fetch_scan_data(test_db_path, scan_id)
|
|
|
|
# Should have expected top-level keys
|
|
assert "metadata" in data
|
|
assert "ports_data" in data
|
|
assert "summary" in data
|
|
|
|
# metadata should have expected structure
|
|
assert "scan_id" in data["metadata"]
|
|
assert "timestamp" in data["metadata"]
|
|
assert "hostname" in data["metadata"]
|
|
|
|
# ports_data should be a dictionary
|
|
assert isinstance(data["ports_data"], dict)
|
|
|
|
# summary should have expected structure
|
|
assert "total_ports" in data["summary"]
|
|
assert "successful_ports" in data["summary"]
|
|
assert "total_cipher_suites" in data["summary"]
|
|
assert "compliant_cipher_suites" in data["summary"]
|
|
|
|
def test_get_scan_data_vulnerabilities(self, test_db_path: str) -> None:
|
|
"""Test that fetch_scan_data includes vulnerability data from direct SQL query."""
|
|
scans = fetch_scans(test_db_path)
|
|
if scans:
|
|
scan_id = scans[0]["scan_id"]
|
|
data = fetch_scan_data(test_db_path, scan_id)
|
|
|
|
# Check that vulnerability data is properly structured
|
|
for port_data in data["ports_data"].values():
|
|
if "vulnerabilities" in port_data:
|
|
for vuln in port_data["vulnerabilities"]:
|
|
assert "type" in vuln
|
|
assert "vulnerable" in vuln
|
|
# This confirms the direct SQL query for vulnerabilities is working
|
|
|
|
def test_get_scan_data_protocol_features(self, test_db_path: str) -> None:
|
|
"""Test that fetch_scan_data includes protocol features data from direct SQL query."""
|
|
scans = fetch_scans(test_db_path)
|
|
if scans:
|
|
scan_id = scans[0]["scan_id"]
|
|
data = fetch_scan_data(test_db_path, scan_id)
|
|
|
|
# Check that protocol features data is properly structured
|
|
for port_data in data["ports_data"].values():
|
|
if "protocol_features" in port_data:
|
|
for feature in port_data["protocol_features"]:
|
|
assert "name" in feature
|
|
assert "supported" in feature
|
|
# This confirms the direct SQL query for protocol features is working
|
|
|
|
def test_get_scan_data_session_features(self, test_db_path: str) -> None:
|
|
"""Test that fetch_scan_data includes session features data from direct SQL query."""
|
|
scans = fetch_scans(test_db_path)
|
|
if scans:
|
|
scan_id = scans[0]["scan_id"]
|
|
data = fetch_scan_data(test_db_path, scan_id)
|
|
|
|
# Check that session features data is properly structured
|
|
for port_data in data["ports_data"].values():
|
|
if "session_features" in port_data:
|
|
for feature in port_data["session_features"]:
|
|
assert "type" in feature
|
|
# This confirms the direct SQL query for session features is working
|
|
|
|
def test_get_scan_data_http_headers(self, test_db_path: str) -> None:
|
|
"""Test that fetch_scan_data includes HTTP headers data from direct SQL query."""
|
|
scans = fetch_scans(test_db_path)
|
|
if scans:
|
|
scan_id = scans[0]["scan_id"]
|
|
data = fetch_scan_data(test_db_path, scan_id)
|
|
|
|
# Check that HTTP headers data is properly structured
|
|
for port_data in data["ports_data"].values():
|
|
if "http_headers" in port_data:
|
|
for header in port_data["http_headers"]:
|
|
assert "name" in header
|
|
assert "value" in header
|
|
assert "is_present" in header
|
|
# This confirms the direct SQL query for HTTP headers is working
|