Add SSH scan support with BSI TR-02102-4 compliance
- 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
This commit is contained in:
1
tests/db/__init__.py
Normal file
1
tests/db/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Database tests package."""
|
||||
130
tests/db/test_query_functions.py
Normal file
130
tests/db/test_query_functions.py
Normal file
@@ -0,0 +1,130 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user