From 318539fd8f7c442615297f1a400e18d1b45d6441 Mon Sep 17 00:00:00 2001 From: "Czar.Echavez" Date: Mon, 9 Oct 2023 13:25:12 +0100 Subject: [PATCH] #1943: apply suggestions from PR + fixing FTP bug + elaborating --- src/primaite/simulator/network/hardware/nodes/computer.py | 2 -- src/primaite/simulator/network/hardware/nodes/router.py | 2 -- src/primaite/simulator/network/hardware/nodes/switch.py | 2 -- src/primaite/simulator/network/networks.py | 2 ++ src/primaite/simulator/network/protocols/ftp.py | 4 ++-- src/primaite/simulator/system/applications/web_browser.py | 4 ++-- src/primaite/simulator/system/services/ftp/ftp_client.py | 6 ++++++ src/primaite/simulator/system/services/ftp/ftp_server.py | 6 +++++- src/primaite/simulator/system/services/ftp/ftp_service.py | 6 ++++++ .../simulator/system/services/web_server/web_server.py | 2 +- 10 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/primaite/simulator/network/hardware/nodes/computer.py b/src/primaite/simulator/network/hardware/nodes/computer.py index 61c62a5f..0480aca9 100644 --- a/src/primaite/simulator/network/hardware/nodes/computer.py +++ b/src/primaite/simulator/network/hardware/nodes/computer.py @@ -2,7 +2,6 @@ from primaite.simulator.network.hardware.base import NIC, Node from primaite.simulator.system.applications.web_browser import WebBrowser from primaite.simulator.system.services.dns.dns_client import DNSClient from primaite.simulator.system.services.ftp.ftp_client import FTPClient -from primaite.simulator.system.services.ftp.ftp_server import FTPServer class Computer(Node): @@ -49,7 +48,6 @@ class Computer(Node): # FTP self.software_manager.install(FTPClient) - self.software_manager.install(FTPServer) # Web Browser self.software_manager.install(WebBrowser) diff --git a/src/primaite/simulator/network/hardware/nodes/router.py b/src/primaite/simulator/network/hardware/nodes/router.py index 90eb5935..092680a7 100644 --- a/src/primaite/simulator/network/hardware/nodes/router.py +++ b/src/primaite/simulator/network/hardware/nodes/router.py @@ -596,8 +596,6 @@ class Router(Node): self.arp.nics = self.nics self.icmp.arp = self.arp - self._install_system_software() - def _get_port_of_nic(self, target_nic: NIC) -> Optional[int]: """ Retrieve the port number for a given NIC. diff --git a/src/primaite/simulator/network/hardware/nodes/switch.py b/src/primaite/simulator/network/hardware/nodes/switch.py index 8b3fe5cd..b7cc1242 100644 --- a/src/primaite/simulator/network/hardware/nodes/switch.py +++ b/src/primaite/simulator/network/hardware/nodes/switch.py @@ -34,8 +34,6 @@ class Switch(Node): port.parent = self port.port_num = port_num - self._install_system_software() - def show(self, markdown: bool = False): """ Prints a table of the SwitchPorts on the Switch. diff --git a/src/primaite/simulator/network/networks.py b/src/primaite/simulator/network/networks.py index e465e08a..be20f89f 100644 --- a/src/primaite/simulator/network/networks.py +++ b/src/primaite/simulator/network/networks.py @@ -11,6 +11,7 @@ from primaite.simulator.network.transmission.transport_layer import Port from primaite.simulator.system.applications.database_client import DatabaseClient from primaite.simulator.system.services.database.database_service import DatabaseService from primaite.simulator.system.services.dns.dns_server import DNSServer +from primaite.simulator.system.services.ftp.ftp_server import FTPServer from primaite.simulator.system.services.red_services.data_manipulation_bot import DataManipulationBot from primaite.simulator.system.services.web_server.web_server import WebServer @@ -268,6 +269,7 @@ def arcd_uc2_network() -> Network: dns_server=IPv4Address("192.168.1.10"), ) backup_server.power_on() + backup_server.software_manager.install(FTPServer) network.connect(endpoint_b=backup_server.ethernet_port[1], endpoint_a=switch_1.switch_ports[4]) # Security Suite diff --git a/src/primaite/simulator/network/protocols/ftp.py b/src/primaite/simulator/network/protocols/ftp.py index 91080219..9ecc7df8 100644 --- a/src/primaite/simulator/network/protocols/ftp.py +++ b/src/primaite/simulator/network/protocols/ftp.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Any, Optional +from typing import Any, Optional, Union from primaite.simulator.network.protocols.packet import DataPacket @@ -51,5 +51,5 @@ class FTPPacket(DataPacket): ftp_command_args: Optional[Any] = None """Arguments for command.""" - status_code: FTPStatusCode = None + status_code: Union[FTPStatusCode, None] = None """Status of the response.""" diff --git a/src/primaite/simulator/system/applications/web_browser.py b/src/primaite/simulator/system/applications/web_browser.py index 4f6b81c1..c48b785e 100644 --- a/src/primaite/simulator/system/applications/web_browser.py +++ b/src/primaite/simulator/system/applications/web_browser.py @@ -19,7 +19,7 @@ class WebBrowser(Application): domain_name_ip_address: Optional[IPv4Address] = None "The IP address of the domain name for the webpage." - latest_response: HttpResponsePacket = None + latest_response: Optional[HttpResponsePacket] = None """Keeps track of the latest HTTP response.""" def __init__(self, **kwargs): @@ -38,7 +38,7 @@ class WebBrowser(Application): :return: A dictionary capturing the current state of the WebBrowser and its child objects. """ - pass + return super().describe_state() def reset_component_for_episode(self, episode: int): """ diff --git a/src/primaite/simulator/system/services/ftp/ftp_client.py b/src/primaite/simulator/system/services/ftp/ftp_client.py index b2a1e8bf..3e286da1 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_client.py +++ b/src/primaite/simulator/system/services/ftp/ftp_client.py @@ -264,6 +264,12 @@ class FTPClient(FTPServiceABC): self.sys_log.error(f"{payload} is not an FTP packet") return False + """ + Ignore ftp payload if status code is None. + + This helps prevent an FTP request loop - FTP client and servers can exist on + the same node. + """ if payload.status_code is None: return False diff --git a/src/primaite/simulator/system/services/ftp/ftp_server.py b/src/primaite/simulator/system/services/ftp/ftp_server.py index d93150e0..23414601 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_server.py +++ b/src/primaite/simulator/system/services/ftp/ftp_server.py @@ -80,7 +80,11 @@ class FTPServer(FTPServiceABC): return False """ - Usually + Ignore ftp payload if status code is defined. + + This means that an FTP server has already handled the packet and + prevents an FTP request loop - FTP client and servers can exist on + the same node. """ if payload.status_code is not None: return False diff --git a/src/primaite/simulator/system/services/ftp/ftp_service.py b/src/primaite/simulator/system/services/ftp/ftp_service.py index 61f83be0..f2c01544 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_service.py +++ b/src/primaite/simulator/system/services/ftp/ftp_service.py @@ -76,6 +76,7 @@ class FTPServiceABC(Service, ABC): dest_ip_address: Optional[IPv4Address] = None, dest_port: Optional[Port] = None, session_id: Optional[str] = None, + is_response: bool = False, ) -> bool: """ Sends data from the host FTP Service's machine to another FTP Service's host machine. @@ -97,6 +98,9 @@ class FTPServiceABC(Service, ABC): :param: session_id: session ID linked to the FTP Packet. Optional. :type: session_id: Optional[str] + + :param: is_response: is true if the data being sent is in response to a request. Default False. + :type: is_response: bool """ # send STOR request payload: FTPPacket = FTPPacket( @@ -108,6 +112,7 @@ class FTPServiceABC(Service, ABC): "real_file_path": file.sim_path if file.real else None, }, packet_payload_size=file.sim_size, + status_code=FTPStatusCode.OK if is_response else None, ) self.sys_log.info(f"{self.name}: Sending file {file.folder.name}/{file.name}") response = self.send( @@ -148,6 +153,7 @@ class FTPServiceABC(Service, ABC): dest_file_name=dest_file_name, dest_folder_name=dest_folder_name, session_id=session_id, + is_response=True, ) except Exception as e: self.sys_log.error(f"Unable to retrieve file from {self.sys_log.hostname}: {e}") diff --git a/src/primaite/simulator/system/services/web_server/web_server.py b/src/primaite/simulator/system/services/web_server/web_server.py index 4566f3b3..f63d5169 100644 --- a/src/primaite/simulator/system/services/web_server/web_server.py +++ b/src/primaite/simulator/system/services/web_server/web_server.py @@ -35,7 +35,7 @@ class WebServer(Service): This is usually HTML, CSS, JS or PHP files requested by browsers to display the webpage. """ # index HTML main file - self.file_system.create_file(file_name="index.html", folder_name="primaite", real=True) + self.file_system.create_file(file_name="index.html", folder_name="primaite") def _process_http_request(self, payload: HttpRequestPacket, session_id: Optional[str] = None) -> bool: """