310 lines
14 KiB
Python
310 lines
14 KiB
Python
from twnet_parser.packet import parse7, TwPacket
|
|
from twnet_parser.messages7.control.keep_alive import CtrlKeepAlive
|
|
from twnet_parser.messages7.control.connect import CtrlConnect
|
|
from twnet_parser.messages7.control.accept import CtrlAccept
|
|
from twnet_parser.messages7.control.close import CtrlClose
|
|
from twnet_parser.messages7.control.token import CtrlToken
|
|
|
|
def test_parse_7_close():
|
|
packet = parse7(b'\x04\x0a\x00\xcf\x2e\xde\x1d\04') # 0.7 close
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.flags.control is True
|
|
|
|
assert packet.messages[0].message_name == 'close'
|
|
assert len(packet.messages) == 1
|
|
|
|
def test_pack_7_close_packet_defaults():
|
|
packet: TwPacket = TwPacket()
|
|
close = CtrlClose()
|
|
packet.messages.append(close)
|
|
data = packet.pack()
|
|
assert data == b'\x04\x00\x00\xff\xff\xff\xff\x04'
|
|
|
|
def test_pack_7_close_packet_token():
|
|
packet: TwPacket = TwPacket()
|
|
packet.header.token = b'\xaa\xbb\xcc\xdd'
|
|
close = CtrlClose()
|
|
packet.messages.append(close)
|
|
data = packet.pack()
|
|
assert data == b'\x04\x00\x00\xaa\xbb\xcc\xdd\x04'
|
|
|
|
def test_pack_7_close_packet_token_and_reason():
|
|
packet: TwPacket = TwPacket()
|
|
packet.header.token = b'\xaa\xbb\xcc\xdd'
|
|
close = CtrlClose(reason = "timeout")
|
|
packet.messages.append(close)
|
|
data = packet.pack()
|
|
assert data == b'\x04\x00\x00\xaa\xbb\xcc\xdd\x04timeout\x00'
|
|
|
|
def test_pack_7_close_packet_set_control_false():
|
|
"""
|
|
This packet is wrong according to tw spec
|
|
|
|
because control is sent but flag not set
|
|
"""
|
|
packet: TwPacket = TwPacket()
|
|
packet.header.token = b'\xaa\xbb\xcc\xdd'
|
|
packet.header.flags.control = False
|
|
close = CtrlClose()
|
|
packet.messages.append(close)
|
|
data = packet.pack()
|
|
assert data == b'\x00\x00\x00\xaa\xbb\xcc\xdd\x04'
|
|
|
|
def test_pack_7_close_packet_set_control_false_and_num_chunks2():
|
|
"""
|
|
This packet is wrong according to tw spec
|
|
|
|
because control is sent but flag not set
|
|
and because num chunks is not set to zero
|
|
"""
|
|
packet: TwPacket = TwPacket()
|
|
packet.header.token = b'\xaa\xbb\xcc\xdd'
|
|
packet.header.flags.control = False
|
|
packet.header.num_chunks = 2
|
|
close = CtrlClose()
|
|
packet.messages.append(close)
|
|
data = packet.pack()
|
|
assert data == b'\x00\x00\x02\xaa\xbb\xcc\xdd\x04'
|
|
|
|
def test_pack_7_close_packet_set_control_true():
|
|
packet: TwPacket = TwPacket()
|
|
packet.header.token = b'\xaa\xbb\xcc\xdd'
|
|
packet.header.flags.control = True
|
|
close = CtrlClose()
|
|
packet.messages.append(close)
|
|
data = packet.pack()
|
|
assert data == b'\x04\x00\x00\xaa\xbb\xcc\xdd\x04'
|
|
|
|
def test_pack_7_close():
|
|
close = CtrlClose()
|
|
data = close.pack()
|
|
assert data == b''
|
|
|
|
def test_parse_7_close_with_reason():
|
|
packet = parse7(b'\x04\x0a\x00\xcf\x2e\xde\x1d\04shutdown\x00') # 0.7 close
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.flags.control is True
|
|
|
|
assert packet.messages[0].message_name == 'close'
|
|
assert len(packet.messages) == 1
|
|
|
|
assert packet.messages[0].reason == 'shutdown'
|
|
|
|
def test_pack_7_close_with_reason():
|
|
close = CtrlClose(reason='foo')
|
|
data = close.pack()
|
|
assert data == b'foo\x00'
|
|
close.unpack(b'hello world\x00')
|
|
assert close.reason == 'hello world'
|
|
|
|
def test_parse_keep_alive7():
|
|
packet = parse7(b'\x04\x04\x00\x5d\x95\xd6\x80\x00')
|
|
# < packet header ><ka>
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.num_chunks == 0
|
|
assert packet.header.flags.control is True
|
|
assert packet.header.token == b'\x5d\x95\xd6\x80'
|
|
|
|
assert packet.messages[0].message_name == 'keep_alive'
|
|
assert len(packet.messages) == 1
|
|
|
|
def test_pack_keep_alive7():
|
|
keep_alive = CtrlKeepAlive()
|
|
data = keep_alive.pack()
|
|
assert data == b''
|
|
|
|
def test_parse_7_ctrl_connect():
|
|
packet = parse7(b'\x04\x00\x00\xcf\x2e\xde\x1d' \
|
|
b'\x01' \
|
|
b'\x58\xeb\x9a\xf4' \
|
|
b'\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00')
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.num_chunks == 0
|
|
assert packet.header.flags.control is True
|
|
assert packet.header.token == b'\xcf\x2e\xde\x1d'
|
|
|
|
assert packet.messages[0].response_token == b'\x58\xeb\x9a\xf4'
|
|
|
|
def test_pack_ctrl_connect7():
|
|
connect = CtrlConnect()
|
|
data = connect.pack()
|
|
|
|
assert 512 == len(data)
|
|
|
|
assert connect.unpack(data) is True
|
|
|
|
assert connect.response_token == b'\xff\xff\xff\xff'
|
|
|
|
# drop too short anti reflection attack payloads
|
|
assert connect.unpack(b'\xff\xff\xff\xff\x00\x00\x00') is False
|
|
|
|
# allow too long anti reflection attack payloads
|
|
assert connect.unpack(b'\xaa\xbb\xcc\xff' + bytes(900)) is True
|
|
|
|
assert connect.response_token == b'\xaa\xbb\xcc\xff'
|
|
|
|
def test_parse_7_accept():
|
|
packet = parse7(b'\x04\x00\x00\x58\xeb\x9a\xf4\x02')
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.num_chunks == 0
|
|
assert packet.header.flags.control is True
|
|
assert packet.header.token == b'\x58\xeb\x9a\xf4'
|
|
|
|
assert packet.messages[0].message_name == 'accept'
|
|
|
|
def test_pack_ctrl_accept7():
|
|
accept = CtrlAccept()
|
|
assert accept.pack() == b''
|
|
|
|
def test_parse_7_ctrl_token_sent_by_client():
|
|
data = b'\x04\x00\x00\xff\xff\xff\xff' \
|
|
b'\x05' \
|
|
b'\x58\xeb\x9a\xf4' \
|
|
b'\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00'
|
|
packet = parse7(data=data, we_are_a_client = False)
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.num_chunks == 0
|
|
assert packet.header.flags.control is True
|
|
assert packet.header.token == b'\xff\xff\xff\xff'
|
|
|
|
assert packet.messages[0].message_name == 'token'
|
|
assert packet.messages[0].response_token == b'\x58\xeb\x9a\xf4'
|
|
|
|
def test_pack_token_sent_by_client7():
|
|
token = CtrlToken()
|
|
token.response_token = b'\x01\xaa\xff\xff'
|
|
data = token.pack(we_are_a_client = True)
|
|
expected = b'\x01\xaa\xff\xff' \
|
|
b'\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
|
|
b'\x00\x00\x00\x00\x00\x00'
|
|
assert expected == data
|
|
|
|
def test_parse_7_ctrl_token_sent_by_server():
|
|
data = b'\x04\x00\x00\x58\xeb\x9a\xf4' \
|
|
b'\x05' \
|
|
b'\xcf\x2e\xde\x1d'
|
|
|
|
# TODO: uncomment this when this issue is solved
|
|
# https://gitlab.com/teeworlds-network/twnet_parser/-/issues/2
|
|
# should we insert some ErrMsg object into messages?
|
|
# should we raise an error?
|
|
# should the messages array be empty?
|
|
# packet = parse7(data=data, we_are_a_client = False)
|
|
# assert len(packet.messages) == 0
|
|
|
|
packet = parse7(data=data, we_are_a_client = True)
|
|
|
|
assert packet.version == '0.7'
|
|
assert packet.header.num_chunks == 0
|
|
assert packet.header.flags.control is True
|
|
assert packet.header.token == b'\x58\xeb\x9a\xf4'
|
|
|
|
assert packet.messages[0].response_token == b'\xcf\x2e\xde\x1d'
|
|
|
|
def test_pack_token_sent_by_server7():
|
|
token = CtrlToken()
|
|
data = token.pack(we_are_a_client = False)
|
|
|
|
assert data == b'\xff\xff\xff\xff'
|