- Fixed FTP client server infinite recursion - ftp server and clients can be installed on the same node, this could cause a loop of requests
- fixed tests broken by merged with dev
This commit is contained in:
@@ -97,6 +97,9 @@ class FTPClient(FTPServiceABC):
|
|||||||
self._connect_to_server(
|
self._connect_to_server(
|
||||||
dest_ip_address=dest_ip_address, dest_port=dest_port, session_id=session_id, is_reattempt=True
|
dest_ip_address=dest_ip_address, dest_port=dest_port, session_id=session_id, is_reattempt=True
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
self.sys_log.error(f"{self.name}: Unable to send FTPPacket")
|
||||||
|
return False
|
||||||
|
|
||||||
def _disconnect_from_server(
|
def _disconnect_from_server(
|
||||||
self, dest_ip_address: Optional[IPv4Address] = None, dest_port: Optional[Port] = Port.FTP
|
self, dest_ip_address: Optional[IPv4Address] = None, dest_port: Optional[Port] = Port.FTP
|
||||||
@@ -247,30 +250,6 @@ class FTPClient(FTPServiceABC):
|
|||||||
self.sys_log.error(f"{self.name}: File {src_folder_name}/{src_file_name} does not exist in FTP server")
|
self.sys_log.error(f"{self.name}: File {src_folder_name}/{src_file_name} does not exist in FTP server")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send(
|
|
||||||
self,
|
|
||||||
payload: FTPPacket,
|
|
||||||
session_id: Optional[str] = None,
|
|
||||||
dest_ip_address: Optional[IPv4Address] = None,
|
|
||||||
dest_port: Optional[Port] = None,
|
|
||||||
**kwargs,
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Sends a payload to the SessionManager.
|
|
||||||
|
|
||||||
:param payload: The payload to be sent.
|
|
||||||
:param dest_ip_address: The ip address of the payload destination.
|
|
||||||
:param dest_port: The port of the payload destination.
|
|
||||||
:param session_id: The Session ID the payload is to originate from. Optional.
|
|
||||||
|
|
||||||
:return: True if successful, False otherwise.
|
|
||||||
"""
|
|
||||||
self.sys_log.info(f"{self.name}: Sending FTP {payload.ftp_command.name} {payload.ftp_command_args}")
|
|
||||||
|
|
||||||
return super().send(
|
|
||||||
payload=payload, dest_ip_address=dest_ip_address, dest_port=dest_port, session_id=session_id, **kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
def receive(self, payload: FTPPacket, session_id: Optional[str] = None, **kwargs) -> bool:
|
def receive(self, payload: FTPPacket, session_id: Optional[str] = None, **kwargs) -> bool:
|
||||||
"""
|
"""
|
||||||
Receives a payload from the SessionManager.
|
Receives a payload from the SessionManager.
|
||||||
@@ -285,5 +264,8 @@ class FTPClient(FTPServiceABC):
|
|||||||
self.sys_log.error(f"{payload} is not an FTP packet")
|
self.sys_log.error(f"{payload} is not an FTP packet")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if payload.status_code is None:
|
||||||
|
return False
|
||||||
|
|
||||||
self._process_ftp_command(payload=payload, session_id=session_id)
|
self._process_ftp_command(payload=payload, session_id=session_id)
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -38,9 +38,11 @@ class FTPServer(FTPServiceABC):
|
|||||||
:param: session_id: session ID linked to the FTP Packet. Optional.
|
:param: session_id: session ID linked to the FTP Packet. Optional.
|
||||||
:type: session_id: Optional[str]
|
:type: session_id: Optional[str]
|
||||||
"""
|
"""
|
||||||
|
# error code by default
|
||||||
|
payload.status_code = FTPStatusCode.ERROR
|
||||||
|
|
||||||
# if server service is down, return error
|
# if server service is down, return error
|
||||||
if self.operating_state != ServiceOperatingState.RUNNING:
|
if self.operating_state != ServiceOperatingState.RUNNING:
|
||||||
payload.status_code = FTPStatusCode.ERROR
|
|
||||||
self.sys_log.error("FTP Server not running")
|
self.sys_log.error("FTP Server not running")
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
@@ -61,9 +63,13 @@ class FTPServer(FTPServiceABC):
|
|||||||
payload.status_code = FTPStatusCode.OK
|
payload.status_code = FTPStatusCode.OK
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
self.sys_log.error(f"Invalid Port {payload.ftp_command_args}")
|
||||||
|
return payload
|
||||||
|
|
||||||
if payload.ftp_command == FTPCommand.QUIT:
|
if payload.ftp_command == FTPCommand.QUIT:
|
||||||
self.connections.pop(session_id)
|
self.connections.pop(session_id)
|
||||||
payload.status_code = FTPStatusCode.OK
|
payload.status_code = FTPStatusCode.OK
|
||||||
|
return payload
|
||||||
|
|
||||||
return super()._process_ftp_command(payload=payload, session_id=session_id, **kwargs)
|
return super()._process_ftp_command(payload=payload, session_id=session_id, **kwargs)
|
||||||
|
|
||||||
@@ -73,5 +79,11 @@ class FTPServer(FTPServiceABC):
|
|||||||
self.sys_log.error(f"{payload} is not an FTP packet")
|
self.sys_log.error(f"{payload} is not an FTP packet")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
"""
|
||||||
|
Usually
|
||||||
|
"""
|
||||||
|
if payload.status_code is not None:
|
||||||
|
return False
|
||||||
|
|
||||||
self.send(self._process_ftp_command(payload=payload, session_id=session_id), session_id)
|
self.send(self._process_ftp_command(payload=payload, session_id=session_id), session_id)
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from ipaddress import IPv4Address
|
from typing import Dict, Optional
|
||||||
from typing import Any, Dict, Optional
|
|
||||||
|
|
||||||
from primaite import getLogger
|
from primaite import getLogger
|
||||||
from primaite.simulator.core import Action, ActionManager
|
from primaite.simulator.core import Action, ActionManager
|
||||||
from primaite.simulator.network.transmission.transport_layer import Port
|
|
||||||
from primaite.simulator.system.software import IOSoftware
|
from primaite.simulator.system.software import IOSoftware
|
||||||
|
|
||||||
_LOGGER = getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
@@ -74,48 +72,6 @@ class Service(IOSoftware):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def send(
|
|
||||||
self,
|
|
||||||
payload: Any,
|
|
||||||
session_id: Optional[str] = None,
|
|
||||||
dest_ip_address: Optional[IPv4Address] = None,
|
|
||||||
dest_port: Optional[Port] = None,
|
|
||||||
**kwargs,
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Sends a payload to the SessionManager.
|
|
||||||
|
|
||||||
:param payload: The payload to be sent.
|
|
||||||
:param dest_ip_address: The ip address of the payload destination.
|
|
||||||
:param dest_port: The port of the payload destination.
|
|
||||||
:param session_id: The Session ID the payload is to originate from. Optional.
|
|
||||||
|
|
||||||
:return: True if successful, False otherwise.
|
|
||||||
"""
|
|
||||||
return super().send(
|
|
||||||
payload=payload, dest_ip_address=dest_ip_address, dest_port=dest_port, session_id=session_id, **kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
def receive(
|
|
||||||
self,
|
|
||||||
payload: Any,
|
|
||||||
session_id: Optional[str] = None,
|
|
||||||
**kwargs,
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Receives a payload from the SessionManager.
|
|
||||||
|
|
||||||
The specifics of how the payload is processed and whether a response payload
|
|
||||||
is generated should be implemented in subclasses.
|
|
||||||
|
|
||||||
:param: payload: The payload to send.
|
|
||||||
:param: session_id: The id of the session
|
|
||||||
|
|
||||||
:return: True if successful, False otherwise.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
"""Stop the service."""
|
"""Stop the service."""
|
||||||
if self.operating_state in [ServiceOperatingState.RUNNING, ServiceOperatingState.PAUSED]:
|
if self.operating_state in [ServiceOperatingState.RUNNING, ServiceOperatingState.PAUSED]:
|
||||||
|
|||||||
@@ -78,12 +78,13 @@ class WebServer(Service):
|
|||||||
response = HTTPResponsePacket(status_code=HTTPStatusCode.BAD_REQUEST, payload=payload)
|
response = HTTPResponsePacket(status_code=HTTPStatusCode.BAD_REQUEST, payload=payload)
|
||||||
try:
|
try:
|
||||||
parsed_url = urlparse(payload.request_url)
|
parsed_url = urlparse(payload.request_url)
|
||||||
|
path = parsed_url.path.strip("/")
|
||||||
|
|
||||||
if parsed_url.path is None or len(parsed_url.path) < 1:
|
if len(path) < 1:
|
||||||
# query succeeded
|
# query succeeded
|
||||||
response.status_code = HTTPStatusCode.OK
|
response.status_code = HTTPStatusCode.OK
|
||||||
|
|
||||||
if parsed_url.path.startswith("/users"):
|
if path.startswith("users"):
|
||||||
# get data from DatabaseServer
|
# get data from DatabaseServer
|
||||||
db_client: DatabaseClient = self.software_manager.software["DatabaseClient"]
|
db_client: DatabaseClient = self.software_manager.software["DatabaseClient"]
|
||||||
# get all users
|
# get all users
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ def dns_server() -> Node:
|
|||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def dns_client() -> Node:
|
def dns_client() -> Node:
|
||||||
node = Computer(
|
node = Computer(
|
||||||
hostname="dns_client", ip_address="192.168.1.11", subnet_mask="255.255.255.0", default_gateway="192.168.1.1"
|
hostname="dns_client",
|
||||||
|
ip_address="192.168.1.11",
|
||||||
|
subnet_mask="255.255.255.0",
|
||||||
|
default_gateway="192.168.1.1",
|
||||||
|
dns_server=IPv4Address("192.168.1.10"),
|
||||||
)
|
)
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import pytest
|
|||||||
from primaite.simulator.network.hardware.base import Node
|
from primaite.simulator.network.hardware.base import Node
|
||||||
from primaite.simulator.network.hardware.nodes.computer import Computer
|
from primaite.simulator.network.hardware.nodes.computer import Computer
|
||||||
from primaite.simulator.network.hardware.nodes.server import Server
|
from primaite.simulator.network.hardware.nodes.server import Server
|
||||||
from primaite.simulator.network.protocols.ftp import FTPCommand, FTPPacket
|
from primaite.simulator.network.protocols.ftp import FTPCommand, FTPPacket, FTPStatusCode
|
||||||
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||||
from primaite.simulator.network.transmission.transport_layer import Port
|
from primaite.simulator.network.transmission.transport_layer import Port
|
||||||
from primaite.simulator.system.services.ftp.ftp_client import FTPClient
|
from primaite.simulator.system.services.ftp.ftp_client import FTPClient
|
||||||
@@ -78,6 +78,7 @@ def test_ftp_client_store_file(ftp_client):
|
|||||||
"file_size": 24,
|
"file_size": 24,
|
||||||
},
|
},
|
||||||
packet_payload_size=24,
|
packet_payload_size=24,
|
||||||
|
status_code=FTPStatusCode.OK,
|
||||||
)
|
)
|
||||||
|
|
||||||
ftp_client_service: FTPClient = ftp_client.software_manager.software["FTPClient"]
|
ftp_client_service: FTPClient = ftp_client.software_manager.software["FTPClient"]
|
||||||
|
|||||||
Reference in New Issue
Block a user