-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest_security.py
More file actions
128 lines (104 loc) · 5.07 KB
/
test_security.py
File metadata and controls
128 lines (104 loc) · 5.07 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import unittest
import os
import platform
import getpass
from unittest.mock import patch, MagicMock
import logging
import json
from device_fingerprinting.security import (
SystemIntegrityChecker,
EnvironmentValidator,
AntiTampering,
SecurityAuditor,
)
# Configure a logger for the auditor to use
auditor_logger = logging.getLogger("TestAuditor")
auditor_logger.setLevel(logging.WARNING)
class TestSecurityModules(unittest.TestCase):
def setUp(self):
"""Set up common resources for tests."""
self.test_file_path = "test_file.txt"
with open(self.test_file_path, "w") as f:
f.write("This is a test file.")
self.integrity_checker = SystemIntegrityChecker()
self.env_validator = EnvironmentValidator()
self.anti_tampering = AntiTampering(self.test_file_path)
# Pass the logger to the auditor
self.auditor = SecurityAuditor(logger=auditor_logger)
def tearDown(self):
"""Clean up created files."""
if os.path.exists(self.test_file_path):
os.remove(self.test_file_path)
if os.path.exists(self.test_file_path + ".mac"):
os.remove(self.test_file_path + ".mac")
# --- SystemIntegrityChecker Tests ---
def test_integrity_checker_get_os_details(self):
"""Test that OS details are retrieved correctly."""
os_details = self.integrity_checker.get_os_details()
self.assertEqual(os_details["os_type"], platform.system())
self.assertEqual(os_details["os_release"], platform.release())
self.assertIn("os_version", os_details)
@patch("psutil.net_if_addrs")
def test_integrity_checker_get_hardware_id(self, mock_net_if_addrs):
"""Test that a hardware ID is generated, mocking network interfaces."""
# Mock the network interface to provide a predictable MAC address
mock_net_if_addrs.return_value = {"Ethernet": [MagicMock(address="00-1A-2B-3C-4D-5E")]}
hw_id = self.integrity_checker.get_hardware_id()
self.assertIsInstance(hw_id, str)
self.assertGreater(len(hw_id), 0)
# Check that it's a SHA256 hash
self.assertEqual(len(hw_id), 64)
# --- EnvironmentValidator Tests ---
@unittest.skipUnless(platform.system() == "Windows", "Windows-specific test")
@patch("ctypes.windll")
def test_is_admin_true_windows(self, mock_windll):
"""Test admin check returns true when running as admin on Windows."""
mock_windll.shell32.IsUserAnAdmin.return_value = 1
self.assertTrue(self.env_validator.is_admin())
@unittest.skipIf(platform.system() == "Windows", "Unix-specific test")
@patch("os.getuid", return_value=0)
def test_is_admin_true_unix(self, mock_getuid):
"""Test admin check returns true when running as root on Unix."""
self.assertTrue(self.env_validator.is_admin())
@patch("builtins.open", new_callable=unittest.mock.mock_open, read_data="GenuineIntel")
def test_is_virtualized_false_for_real_cpu(self, mock_open):
"""Test virtualization check returns false on a real CPU."""
self.assertFalse(self.env_validator.is_virtualized())
@patch("psutil.boot_time", return_value=12345.0)
def test_is_recently_booted_false(self, mock_boot_time):
"""Test that a long uptime returns false."""
self.assertFalse(self.env_validator.is_recently_booted(threshold_seconds=10))
# --- AntiTampering Tests ---
def test_anti_tampering_generate_and_verify_mac(self):
"""Test MAC generation and successful verification."""
self.anti_tampering.generate_mac()
self.assertTrue(os.path.exists(self.test_file_path + ".mac"))
self.assertTrue(self.anti_tampering.verify_mac())
def test_anti_tampering_verify_mac_fails_on_tamper(self):
"""Test that MAC verification fails if the file is tampered with."""
self.anti_tampering.generate_mac()
# Tamper with the file
with open(self.test_file_path, "a") as f:
f.write(" some tampered data.")
self.assertFalse(self.anti_tampering.verify_mac())
# --- SecurityAuditor Tests ---
@patch.object(auditor_logger, "warning")
def test_auditor_log_security_event(self, mock_log_warning):
"""Test that security events are logged via the provided logger."""
event_details = {"detail": "some data"}
self.auditor.log_security_event("Test Event", "High", event_details)
mock_log_warning.assert_called_once()
# The argument to the logger should be a JSON string
call_args = mock_log_warning.call_args[0][0]
log_data = json.loads(call_args)
self.assertEqual(log_data["event"], "Test Event")
self.assertEqual(log_data["level"], "High")
self.assertEqual(log_data["details"], event_details)
def test_auditor_get_system_state(self):
"""Test that system state is captured."""
state = self.auditor.get_system_state()
self.assertEqual(state["user"], getpass.getuser())
self.assertIn("os_details", state)
self.assertIn("running_processes", state)
if __name__ == "__main__":
unittest.main()