diff --git a/conpot/protocols/IEC104/IEC104_server.py b/conpot/protocols/IEC104/IEC104_server.py index d66761ab..d0873f46 100644 --- a/conpot/protocols/IEC104/IEC104_server.py +++ b/conpot/protocols/IEC104/IEC104_server.py @@ -80,38 +80,29 @@ def handle(self, sock, address): request += new_byte # check if IEC 104 packet or for the first occurrence of the indication 0x68 for IEC 104 - for elem in list(request): - if 0x68 == elem: - index = request.index(elem) + if request[0] == 0x68: + timeout_t3.cancel() + response = None + # check which frame type + if not (request[2] & 0x01): # i_frame + response = iec104_handler.handle_i_frame(request) + elif request[2] & 0x01 and not ( + request[2] & 0x02 + ): # s_frame + iec104_handler.handle_s_frame(request) + elif request[2] & 0x03: # u_frame + response = iec104_handler.handle_u_frame(request) + else: + logger.warning( + "%s ---> No valid IEC104 type (%s)", + address, + session.id, + ) - iec_request = request[index:] - timeout_t3.cancel() - response = None - # check which frame type - if not (iec_request[2] & 0x01): # i_frame - response = iec104_handler.handle_i_frame( - iec_request - ) - elif iec_request[2] & 0x01 and not ( - iec_request[2] & 0x02 - ): # s_frame - iec104_handler.handle_s_frame(iec_request) - elif iec_request[2] & 0x03: # u_frame - response = iec104_handler.handle_u_frame( - iec_request - ) - else: - logger.warning( - "%s ---> No valid IEC104 type (%s)", - address, - session.id, - ) - - if response: - for resp_packet in response: - if resp_packet: - sock.send(resp_packet) - break + if response: + for resp_packet in response: + if resp_packet: + sock.send(resp_packet) except Timeout_t3: pkt = iec104_handler.send_104frame(TESTFR_act) diff --git a/conpot/tests/test_iec104_server.py b/conpot/tests/test_iec104_server.py index 4d4f3621..d428a891 100644 --- a/conpot/tests/test_iec104_server.py +++ b/conpot/tests/test_iec104_server.py @@ -223,3 +223,19 @@ def test_failing_connection_connection_lost_event(self, mock_timeout): self.assertEqual("CONNECTION_LOST", con_lost_event["data"]["type"]) s.close() + + @patch("conpot.protocols.IEC104.IEC104_server.gevent._socket3.socket.recv") + def test_connection_times_out_if_traffic_starts_with_wrong_prefix( + self, mock_timeout + ): + """ + Objective: Test if server ignores traffic starting with wrong prefix + """ + mock_timeout.side_effect = TimeoutError() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(1) + s.connect(("127.0.0.1", 2404)) + packet = frames.u_frame(Start=0x67).build() + s.send(packet) + with self.assertRaises(TimeoutError): + s.recv(6)