Skip to content

Commit

Permalink
Various stabilizations (secdev#3095)
Browse files Browse the repository at this point in the history
* Upgrade run_tests.bat

* Make TCP_client slightly more stable

* Order TESTFILES in UTscapy

* Stabilize various tests
  • Loading branch information
gpotter2 authored and bzalkilani committed Jun 14, 2022
1 parent f622b30 commit 29b666f
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 39 deletions.
8 changes: 5 additions & 3 deletions scapy/autorun.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@ def __init__(self, debug=None):
self.debug = debug

def write(self, x):
if self.debug:
# Object can be in the middle of being destroyed.
if getattr(self, "debug", None):
self.debug.write(x)
self.s += x
if getattr(self, "s", None) is not None:
self.s += x

def flush(self):
if self.debug:
if getattr(self, "debug", None):
self.debug.flush()


Expand Down
4 changes: 4 additions & 0 deletions scapy/layers/inet.py
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,10 @@ def stop_send_ack(self, pkt):
self.l4[TCP].ack = pkt[TCP].seq + 1
self.send(self.l4)

@ATMT.timeout(SYN_SENT, 1)
def syn_ack_timeout(self):
raise self.CLOSED()

@ATMT.timeout(STOP_SENT_FIN_ACK, 1)
def stop_ack_timeout(self):
raise self.CLOSED()
Expand Down
2 changes: 1 addition & 1 deletion scapy/tools/UTscapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ def resolve_testfiles(TESTFILES):
for tfile in TESTFILES[:]:
if "*" in tfile:
TESTFILES.remove(tfile)
TESTFILES.extend(glob.glob(tfile))
TESTFILES.extend(sorted(glob.glob(tfile)))
return TESTFILES


Expand Down
2 changes: 2 additions & 0 deletions test/contrib/isotp.uts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
% Regression tests for ISOTP

~ vcan_socket

+ Configuration
~ conf

Expand Down
2 changes: 1 addition & 1 deletion test/run_tests
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ then
fi

# Run tox
export UT_FLAGS="-K tcpdump -K manufdb -K wireshark -K ci_only"
export UT_FLAGS="-K tcpdump -K manufdb -K wireshark -K ci_only -K vcan_socket"
export SIMPLE_TESTS="true"
PYVER=$($PYTHON -c "import sys; print('.'.join(sys.version.split('.')[:2]))")
${DIR}/.config/ci/test.sh $PYVER non_root
Expand Down
27 changes: 23 additions & 4 deletions test/run_tests.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,35 @@
set MYDIR=%~dp0..
set PWD=%MYDIR%
set PYTHONPATH=%MYDIR%
REM shift will not work with %*
REM Note: shift will not work with %*
REM ### Get args, Handle Python version ###
set "_args=%*"
IF "%1" == "--2" (
IF "%1" == "-2" (
set PYTHON=python
set "_args=%_args:~3%"
) ELSE IF "%1" == "--3" (
) ELSE IF "%1" == "-3" (
set PYTHON=python3
set "_args=%_args:~3%"
)
IF "%PYTHON%" == "" set PYTHON=python3
WHERE %PYTHON% >nul 2>&1
IF %ERRORLEVEL% NEQ 0 set PYTHON=python
%PYTHON% "%MYDIR%\scapy\tools\UTscapy.py" %_args%
REM Reset Error level
VERIFY > nul
echo ##### Starting Unit tests #####
REM ### Check no-argument mode ###
IF "%_args%" == "" (
REM Check for tox
%PYTHON% -m tox --version >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
echo Tox not installed !
pause
exit 1
)
REM Run tox
%PYTHON% -m tox -- -K tcpdump -K manufdb -K wireshark -K ci_only
pause
exit 0
)
REM ### Start UTScapy normally ###
%PYTHON% "%MYDIR%\scapy\tools\UTscapy.py" %_args%
92 changes: 63 additions & 29 deletions test/sendsniff.uts
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,42 @@ from threading import Thread

tap0, tap1 = [TunTapInterface("tap%d" % i) for i in range(2)]

if six.PY2:
chk_kwargs = {}
else:
chk_kwargs = {"timeout": 3}

if LINUX:
for i in range(2):
assert subprocess.check_call(["ip", "link", "set", "tap%d" % i, "up"]) == 0
assert subprocess.check_call(["ip", "link", "set", "tap%d" % i, "up"], **chk_kwargs) == 0
else:
for i in range(2):
assert subprocess.check_call(["ifconfig", "tap%d" % i, "up"]) == 0
assert subprocess.check_call(["ifconfig", "tap%d" % i, "up"], **chk_kwargs) == 0

= Run a sniff thread on the tap1 **interface**
* It will terminate when 5 IP packets from 192.0.2.1 have been sniffed
started = threading.Event()
t_sniff = Thread(
target=sniff,
kwargs={"iface": "tap1", "count": 5, "prn": Packet.summary,
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1"},
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1",
"started_callback": started.set},
name="tests sniff 1")
t_sniff.start()
started.wait(timeout=5)

= Run a bridge_and_sniff thread between the taps **sockets**
* It will terminate when 5 IP packets from 192.0.2.1 have been forwarded
started = threading.Event()
t_bridge = Thread(target=bridge_and_sniff, args=(tap0, tap1),
kwargs={"store": False, "count": 5, 'prn': Packet.summary,
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1"},
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1",
"started_callback": started.set},
name="tests bridge_and_sniff 1")
t_bridge.start()
started.wait(timeout=5)

= Send five IP packets from 192.0.2.1 to the tap0 **interface**
time.sleep(1)
sendp([Ether(dst=ETHER_BROADCAST) / IP(src="192.0.2.1") / ICMP()], iface="tap0",
count=5)

Expand All @@ -52,12 +62,15 @@ assert not t_sniff.is_alive()

= Run a sniff thread on the tap1 **interface**
* It will terminate when 5 IP packets from 198.51.100.1 have been sniffed
started = threading.Event()
t_sniff = Thread(
target=sniff,
kwargs={"iface": "tap1", "count": 5, "prn": Packet.summary,
"lfilter": lambda p: IP in p and p[IP].src == "198.51.100.1"},
"lfilter": lambda p: IP in p and p[IP].src == "198.51.100.1",
"started_callback": started.set},
name="tests sniff 2")
t_sniff.start()
started.wait(timeout=5)

= Run a bridge_and_sniff thread between the taps **sockets**
* It will "NAT" packets from 192.0.2.1 to 198.51.100.1 and will terminate when 5 IP packets have been forwarded
Expand All @@ -68,15 +81,17 @@ def nat_1_2(pkt):
return pkt
return False

started = threading.Event()
t_bridge = Thread(target=bridge_and_sniff, args=(tap0, tap1),
kwargs={"store": False, "count": 5, 'prn': Packet.summary,
"xfrm12": nat_1_2,
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1"},
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1",
"started_callback": started.set},
name="tests bridge_and_sniff 2")
t_bridge.start()
started.wait(timeout=5)

= Send five IP packets from 192.0.2.1 to the tap0 **interface**
time.sleep(1)
sendp([Ether(dst=ETHER_BROADCAST) / IP(src="192.0.2.1") / ICMP()], iface="tap0",
count=5)

Expand Down Expand Up @@ -108,42 +123,48 @@ from threading import Thread

tun0, tun1 = [TunTapInterface("tun%d" % i) for i in range(2)]

if six.PY2:
chk_kwargs = {}
else:
chk_kwargs = {"timeout": 3}

if LINUX:
for i in range(2):
assert subprocess.check_call(["ip", "link", "set", "tun%d" % i, "up"]) == 0
assert subprocess.check_call(["ip", "link", "set", "tun%d" % i, "up"], **chk_kwargs) == 0
assert subprocess.check_call([
"ip", "addr", "change",
"192.0.2.1", "peer", "192.0.2.2", "dev", "tun0"]) == 0
"192.0.2.1", "peer", "192.0.2.2", "dev", "tun0"], **chk_kwargs) == 0
else:
for i in range(2):
assert subprocess.check_call(["ifconfig", "tun%d" % i, "up"]) == 0
assert subprocess.check_call(["ifconfig", "tun0", "192.0.2.1", "192.0.2.2"]) == 0

print('waiting a bit...')
import time
time.sleep(10)
assert subprocess.check_call(["ifconfig", "tun%d" % i, "up"], **chk_kwargs) == 0
assert subprocess.check_call(["ifconfig", "tun0", "192.0.2.1", "192.0.2.2"], **chk_kwargs) == 0

= Run a sniff thread on the tun1 **interface**
* It will terminate when 5 IP packets from 192.0.2.1 have been sniffed
started = threading.Event()
t_sniff = Thread(target=sniff,
kwargs={"iface": "tun1", "count": 5,
"prn": Packet.summary,
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1"},
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1",
"started_callback": started.set},
name="tests sniff 3")

t_sniff.start()
started.wait(timeout=5)

= Run a bridge_and_sniff thread between the tuns **sockets**
* It will terminate when 5 IP packets from 192.0.2.1 have been forwarded.
started = threading.Event()
t_bridge = Thread(target=bridge_and_sniff, args=(tun0, tun1),
kwargs={"store": False, "count": 5, 'prn': Packet.summary,
"xfrm12": lambda pkt: pkt,
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1"},
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1",
"started_callback": started.set},
name="tests bridge_and_sniff 3")
t_bridge.start()
started.wait(timeout=5)

= Send five IP packets from 192.0.2.1 to the tun0 **interface**
time.sleep(1)
conf.route.add(net="192.0.2.2/32", dev="tun0")
send([IP(src="192.0.2.1", dst="192.0.2.2") / ICMP()], count=5, iface="tun0")
conf.route.delt(net="192.0.2.2/32", dev="tun0")
Expand All @@ -156,12 +177,15 @@ assert not t_sniff.is_alive()

= Run a sniff thread on the tun1 **interface**
* It will terminate when 5 IP packets from 198.51.100.1 have been sniffed
started = threading.Event()
t_sniff = Thread(target=sniff,
kwargs={"iface": "tun1", "count": 5, "prn": Packet.summary,
"lfilter": lambda p: IP in p and p[IP].src == "198.51.100.1"},
"lfilter": lambda p: IP in p and p[IP].src == "198.51.100.1",
"started_callback": started.set},
name="tests sniff 4")

t_sniff.start()
started.wait(timeout=5)

= Run a bridge_and_sniff thread between the tuns **sockets**
* It will "NAT" packets from 192.0.2.1 to 198.51.100.1 and will terminate when 5 IP packets have been forwarded
Expand All @@ -172,15 +196,17 @@ def nat_1_2(pkt):
return pkt
return False

started = threading.Event()
t_bridge = Thread(target=bridge_and_sniff, args=(tun0, tun1),
kwargs={"store": False, "count": 5, 'prn': Packet.summary,
"xfrm12": nat_1_2,
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1"},
"lfilter": lambda p: IP in p and p[IP].src == "192.0.2.1",
"started_callback": started.set},
name="tests bridge_and_sniff 4")
t_bridge.start()
started.wait(timeout=5)

= Send five IP packets from 192.0.2.1 to the tun0 **interface**
time.sleep(1)
conf.route.add(net="192.0.2.2/32", dev="tun0")
send([IP(src="192.0.2.1", dst="192.0.2.2") / ICMP()], count=5, iface="tun0")
conf.route.delt(net="192.0.2.2/32", dev="tun0")
Expand Down Expand Up @@ -224,17 +250,19 @@ with VEthPair('a_0', 'a_1') as veth_0:
global xfrm_count
xfrm_count[pkt.sniffed_on] = xfrm_count[pkt.sniffed_on] + 1
return True
started = threading.Event()
t_bridge = Thread(target=bridge_and_sniff,
args=('a_0', 'b_0'),
kwargs={
'xfrm12': xfrm_x,
'xfrm21': xfrm_x,
'store': False,
'count': 4,
'lfilter': lambda p: Ether in p and p[Ether].type == 0xbeef},
'lfilter': lambda p: Ether in p and p[Ether].type == 0xbeef,
"started_callback": started.set},
name="tests bridge_and_sniff VEthPair")
t_bridge.start()
time.sleep(1)
started.wait(timeout=5)
# send frames in both directions
for if_name in ['a_1', 'b_1', 'a_1', 'b_1']:
sendp([Ether(type=0xbeef) /
Expand Down Expand Up @@ -262,10 +290,15 @@ import time

tap0 = TunTapInterface("tap0")

if six.PY2:
chk_kwargs = {}
else:
chk_kwargs = {"timeout": 3}

if LINUX:
assert subprocess.check_call(["ip", "link", "set", "tap0", "up"]) == 0
assert subprocess.check_call(["ip", "link", "set", "tap0", "up"], **chk_kwargs) == 0
else:
assert subprocess.check_call(["ifconfig", "tap0", "up"]) == 0
assert subprocess.check_call(["ifconfig", "tap0", "up"], **chk_kwargs) == 0

= Check for arpleak

Expand Down Expand Up @@ -296,13 +329,16 @@ def answer_arp_leak(pkt):
tap0.send(ans)
print('Answered!')

started = threading.Event()
t_answer = Thread(
target=sniff,
kwargs={"prn": answer_arp_leak, "timeout": 10, "store": False,
"opened_socket": tap0},
"opened_socket": tap0,
"started_callback": started.set},
name="tests answer_arp_leak")

t_answer.start()
started.wait(timeout=5)

@mock.patch("scapy.layers.l2.get_if_addr")
@mock.patch("scapy.layers.l2.get_if_hwaddr")
Expand All @@ -312,8 +348,6 @@ def test_arpleak(mock_get_if_hwaddr, mock_get_if_addr, hwlen=255, plen=255):
mock_get_if_hwaddr.side_effect = lambda _: "00:01:02:03:04:05"
return arpleak("192.0.2.2/31", timeout=2, hwlen=hwlen, plen=plen)

time.sleep(2)

ans, unans = test_arpleak()
assert len(ans) == 1
assert len(unans) == 1
Expand Down
3 changes: 2 additions & 1 deletion test/tls/tests_tls_netaccess.uts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ def run_openssl_client(msg, suite="", version="", tls13=False, client_auth=False
if sess_out:
args.extend(["-sess_out", sess_out])
p = subprocess.Popen(
args,
" ".join(args),
shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
msg += b"\nstop_server\n"
Expand Down

0 comments on commit 29b666f

Please sign in to comment.