Files
compliance-scan/tests/iana/test_iana_ssh_import_issue.py
Heiko f60de7c2da 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
2026-01-23 11:05:01 +01:00

249 lines
8.6 KiB
Python

"""Test to verify that IANA SSH tables remain empty due to import issues."""
import argparse
import os
import sqlite3
import tempfile
from pathlib import Path
from unittest.mock import patch
from src.sslysze_scan.commands.update_iana import handle_update_iana_command
def test_iana_ssh_tables_populated_after_successful_import():
"""Test that IANA SSH tables are populated after successful import.
This test verifies that the IANA SSH parameter import now succeeds
and populates the SSH tables with data using local XML fixtures.
"""
# Use the template database for this test
import shutil
template_db = (
Path(__file__).parent.parent.parent
/ "src"
/ "sslysze_scan"
/ "data"
/ "crypto_standards.db"
)
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as temp_db:
db_path = temp_db.name
# Copy the template database to use as our test database
shutil.copy2(template_db, db_path)
# Path to local XML fixtures
fixtures_dir = Path(__file__).parent.parent / "fixtures" / "iana_xml"
def mock_fetch_xml(url: str, timeout: int = 30) -> str:
"""Mock function that returns local XML files instead of downloading."""
if "tls-parameters" in url:
xml_file = fixtures_dir / "tls-parameters-minimal.xml"
elif "ikev2-parameters" in url:
xml_file = fixtures_dir / "ikev2-parameters-minimal.xml"
elif "ssh-parameters" in url:
xml_file = fixtures_dir / "ssh-parameters-minimal.xml"
else:
raise ValueError(f"Unknown URL: {url}")
return xml_file.read_text(encoding="utf-8")
try:
# Check initial state of SSH tables
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Count initial entries in IANA SSH tables
ssh_tables = [
"iana_ssh_kex_methods",
"iana_ssh_encryption_algorithms",
"iana_ssh_mac_algorithms",
"iana_ssh_compression_algorithms",
]
initial_counts = {}
for table in ssh_tables:
cursor.execute(f"SELECT COUNT(*) FROM {table}")
initial_counts[table] = cursor.fetchone()[0]
conn.close()
# Run the IANA update command directly with mocked fetch and validation
with (
patch(
"src.sslysze_scan.commands.update_iana.fetch_xml_from_url",
side_effect=mock_fetch_xml,
),
patch(
"src.sslysze_scan.iana_validator.MIN_ROWS",
{
"iana_tls_cipher_suites": 1,
"iana_tls_signature_schemes": 1,
"iana_tls_supported_groups": 1,
"iana_tls_alerts": 1,
"iana_tls_content_types": 1,
"iana_ikev2_encryption_algorithms": 1,
"iana_ikev2_prf_algorithms": 1,
"iana_ikev2_integrity_algorithms": 1,
"iana_ikev2_dh_groups": 1,
"iana_ikev2_authentication_methods": 1,
"iana_ssh_kex_methods": 1,
"iana_ssh_encryption_algorithms": 1,
"iana_ssh_mac_algorithms": 1,
"iana_ssh_compression_algorithms": 1,
},
),
):
args = argparse.Namespace(database=db_path)
result = handle_update_iana_command(args)
# Verify that the command succeeded
assert result == 0, (
f"IANA update command should succeed, got return code: {result}"
)
# Connect to database again to check if tables are now populated
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Check that SSH tables are now populated and get final counts
final_counts = {}
for table in ssh_tables:
cursor.execute(f"SELECT COUNT(*) FROM {table}")
final_count = cursor.fetchone()[0]
final_counts[table] = final_count
# The tables should now have data after successful import
# Note: Using minimal fixtures, so counts may be lower than full data
assert final_count > 0, (
f"Table {table} should be populated after successful import"
)
conn.close()
print(
"Test confirmed: IANA SSH tables are properly populated after "
"successful import using minimal fixtures"
)
print(f"Initial counts (from template DB): {initial_counts}")
print(f"Final counts (from minimal fixtures): {final_counts}")
finally:
# Clean up temporary database
if os.path.exists(db_path):
os.unlink(db_path)
def test_compliance_works_with_populated_iana_ssh_tables():
"""Test that compliance checking works appropriately when IANA SSH tables are populated."""
# Use the template database for this test
import shutil
template_db = (
Path(__file__).parent.parent.parent
/ "src"
/ "sslysze_scan"
/ "data"
/ "crypto_standards.db"
)
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as temp_db:
db_path = temp_db.name
# Copy the template database to use as our test database
shutil.copy2(template_db, db_path)
try:
# Connect to database to check SSH table status
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Verify that IANA SSH tables are now populated
cursor.execute("SELECT COUNT(*) FROM iana_ssh_kex_methods")
kex_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM iana_ssh_encryption_algorithms")
enc_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM iana_ssh_mac_algorithms")
mac_count = cursor.fetchone()[0]
conn.close()
# Verify that the tables are populated (this is the corrected behavior)
assert kex_count > 0, (
f"IANA SSH KEX table should be populated but has {kex_count} entries"
)
assert enc_count > 0, (
f"IANA SSH encryption table should be populated but has {enc_count} entries"
)
assert mac_count > 0, (
f"IANA SSH MAC table should be populated but has {mac_count} entries"
)
print(
f"Confirmed populated SSH tables: KEX={kex_count}, ENC={enc_count}, MAC={mac_count}"
)
finally:
# Clean up temporary database
if os.path.exists(db_path):
os.unlink(db_path)
def test_iana_ssh_tables_should_not_be_empty_but_are():
"""Test that fails if IANA SSH tables are empty (demonstrating the issue).
This test expects SSH tables to have data but will fail because they are empty
due to the import column mismatch issue.
"""
# Use the template database for this test
import shutil
template_db = (
Path(__file__).parent.parent.parent
/ "src"
/ "sslysze_scan"
/ "data"
/ "crypto_standards.db"
)
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as temp_db:
db_path = temp_db.name
# Copy the template database to use as our test database
shutil.copy2(template_db, db_path)
try:
# Connect to database to check SSH table status
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Check that IANA SSH tables are empty (this demonstrates the problem)
cursor.execute("SELECT COUNT(*) FROM iana_ssh_kex_methods")
kex_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM iana_ssh_encryption_algorithms")
enc_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM iana_ssh_mac_algorithms")
mac_count = cursor.fetchone()[0]
conn.close()
# This assertion will fail, demonstrating the issue
# The tables SHOULD have entries after a successful IANA import, but they don't
assert kex_count > 0, (
f"IANA SSH KEX table should have entries but has {kex_count} - this demonstrates the import issue"
)
assert enc_count > 0, (
f"IANA SSH encryption table should have entries but has {enc_count} - this demonstrates the import issue"
)
assert mac_count > 0, (
f"IANA SSH MAC table should have entries but has {mac_count} - this demonstrates the import issue"
)
print(
f"SSH tables have data as expected: KEX={kex_count}, ENC={enc_count}, MAC={mac_count}"
)
finally:
# Clean up temporary database
if os.path.exists(db_path):
os.unlink(db_path)