-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_app.py
More file actions
161 lines (115 loc) · 5.31 KB
/
Copy pathtest_app.py
File metadata and controls
161 lines (115 loc) · 5.31 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import pytest
from app import detect_arp_spoofing, get_vendor, PROBES
# ─────────────────────────────────────────────
# detect_arp_spoofing
# ─────────────────────────────────────────────
@pytest.mark.parametrize("devices, expected", [
([], {}),
([{"ip": "192.168.1.1", "mac": "aa:bb:cc:dd:ee:ff"}], {}),
])
def test_basic_cases(devices, expected):
assert detect_arp_spoofing(devices) == expected
def test_no_spoofing():
devices = [
{"ip": "192.168.1.1", "mac": "aa:bb:cc:dd:ee:01"},
{"ip": "192.168.1.2", "mac": "aa:bb:cc:dd:ee:02"},
{"ip": "192.168.1.3", "mac": "aa:bb:cc:dd:ee:03"},
]
assert detect_arp_spoofing(devices) == {}
def test_duplicate_mac_different_ips():
devices = [
{"ip": "192.168.1.1", "mac": "aa:bb:cc:dd:ee:ff"},
{"ip": "192.168.1.254", "mac": "aa:bb:cc:dd:ee:ff"},
{"ip": "192.168.1.2", "mac": "aa:bb:cc:dd:ee:02"},
]
result = detect_arp_spoofing(devices)
assert "aa:bb:cc:dd:ee:ff" in result
assert set(result["aa:bb:cc:dd:ee:ff"]) == {"192.168.1.1", "192.168.1.254"}
def test_same_ip_different_mac():
devices = [
{"ip": "192.168.1.1", "mac": "aa:aa:aa:aa:aa:aa"},
{"ip": "192.168.1.1", "mac": "bb:bb:bb:bb:bb:bb"},
]
result = detect_arp_spoofing(devices)
assert "192.168.1.1" in result
assert set(result["192.168.1.1"]) == {"aa:aa:aa:aa:aa:aa", "bb:bb:bb:bb:bb:bb"}
def test_mac_case_insensitive():
devices = [
{"ip": "192.168.1.1", "mac": "aa:bb:cc:dd:ee:ff"},
{"ip": "192.168.1.2", "mac": "AA:BB:CC:DD:EE:FF"},
]
result = detect_arp_spoofing(devices)
assert "aa:bb:cc:dd:ee:ff" in result
def test_duplicate_same_entry_not_flagged():
devices = [
{"ip": "192.168.1.1", "mac": "aa:bb:cc:dd:ee:ff"},
{"ip": "192.168.1.1", "mac": "aa:bb:cc:dd:ee:ff"},
]
assert detect_arp_spoofing(devices) == {}
def test_large_input_no_spoofing():
devices = [
{"ip": f"192.168.1.{i}", "mac": f"aa:bb:cc:dd:ee:{i:02x}"}
for i in range(1, 255)
]
assert detect_arp_spoofing(devices) == {}
def test_large_input_one_spoof():
devices = [
{"ip": f"192.168.1.{i}", "mac": f"aa:bb:cc:dd:ee:{i:02x}"}
for i in range(1, 255)
]
devices.append({"ip": "10.0.0.1", "mac": "aa:bb:cc:dd:ee:01"})
result = detect_arp_spoofing(devices)
assert "aa:bb:cc:dd:ee:01" in result
# ─────────────────────────────────────────────
# PROBES
# ─────────────────────────────────────────────
def test_probes_http_ports_send_head():
for port in [80, 443, 8080, 8443]:
assert port in PROBES
assert b"HEAD" in PROBES[port]
def test_probes_silent_services_are_none():
# These services send a greeting on connect — no probe needed
for port in [22, 3306, 5432, 27017]:
assert port in PROBES
assert PROBES[port] is None
def test_probes_redis():
assert PROBES[6379] == b"INFO\r\n"
def test_probes_ftp():
assert PROBES[21] == b"HELP\r\n"
def test_probes_smtp():
assert b"EHLO" in PROBES[25]
# ─────────────────────────────────────────────
# get_vendor
# ─────────────────────────────────────────────
def test_get_vendor_returns_string():
result = get_vendor("00:50:56:aa:bb:cc") # VMware OUI
assert isinstance(result, str)
def test_get_vendor_unknown_returns_string():
result = get_vendor("02:00:00:00:00:00") # locally administered, not in DB
assert result == "Unknown"
def test_get_vendor_invalid_mac():
result = get_vendor("not-a-mac")
assert result == "Unknown"
# ─────────────────────────────────────────────
# Watch mode set logic
# ─────────────────────────────────────────────
def test_watch_new_device_detected():
previous = {"aa:bb:cc:dd:ee:01", "aa:bb:cc:dd:ee:02"}
current = {"aa:bb:cc:dd:ee:01", "aa:bb:cc:dd:ee:02", "aa:bb:cc:dd:ee:03"}
assert current - previous == {"aa:bb:cc:dd:ee:03"}
assert previous - current == set()
def test_watch_device_left():
previous = {"aa:bb:cc:dd:ee:01", "aa:bb:cc:dd:ee:02"}
current = {"aa:bb:cc:dd:ee:01"}
assert current - previous == set()
assert previous - current == {"aa:bb:cc:dd:ee:02"}
def test_watch_device_rejoins():
# Simulates WiFi toggle: device was gone last scan, now it's back
previous = {"aa:bb:cc:dd:ee:01"} # phone was absent
current = {"aa:bb:cc:dd:ee:01", "aa:bb:cc:dd:ee:02"} # phone returned
new_macs = current - previous
assert "aa:bb:cc:dd:ee:02" in new_macs # triggers alert again
def test_watch_no_change():
macs = {"aa:bb:cc:dd:ee:01", "aa:bb:cc:dd:ee:02"}
assert macs - macs == set()
assert macs - macs == set()