Merge remote-tracking branch 'origin/dev' into feature/2350-confirm-action-observation-space-conforms-to-CAOS-0.7

This commit is contained in:
Czar Echavez
2024-03-12 09:11:30 +00:00
35 changed files with 781 additions and 232 deletions

View File

@@ -12,6 +12,8 @@ def test_passing_actions_down(monkeypatch) -> None:
sim = Simulation()
pc1 = Computer(hostname="PC-1", ip_address="10.10.1.1", subnet_mask="255.255.255.0")
pc1.start_up_duration = 0
pc1.power_on()
pc2 = Computer(hostname="PC-2", ip_address="10.10.1.2", subnet_mask="255.255.255.0")
srv = Server(hostname="WEBSERVER", ip_address="10.10.1.100", subnet_mask="255.255.255.0")
s1 = Switch(hostname="switch1")

View File

@@ -125,8 +125,8 @@ def test_describe_state_nmne(uc2_network):
web_server_nic_state = web_server_nic.describe_state()
db_server_nic_state = db_server_nic.describe_state()
uc2_network.apply_timestep(timestep=0)
assert web_server_nic_state["nmne"] == {}
assert db_server_nic_state["nmne"] == {}
assert web_server_nic_state["nmne"] == {"direction": {"outbound": {"keywords": {"*": 1}}}}
assert db_server_nic_state["nmne"] == {"direction": {"inbound": {"keywords": {"*": 1}}}}
# Perform another "DELETE" query
db_client.query("DELETE")
@@ -135,8 +135,8 @@ def test_describe_state_nmne(uc2_network):
web_server_nic_state = web_server_nic.describe_state()
db_server_nic_state = db_server_nic.describe_state()
uc2_network.apply_timestep(timestep=0)
assert web_server_nic_state["nmne"] == {"direction": {"outbound": {"keywords": {"*": 1}}}}
assert db_server_nic_state["nmne"] == {"direction": {"inbound": {"keywords": {"*": 1}}}}
assert web_server_nic_state["nmne"] == {"direction": {"outbound": {"keywords": {"*": 2}}}}
assert db_server_nic_state["nmne"] == {"direction": {"inbound": {"keywords": {"*": 2}}}}
def test_capture_nmne_observations(uc2_network):

View File

@@ -0,0 +1,160 @@
# some test cases:
# 0. test that sending a request to a valid target results in a success
# 1. test that sending a request to a component that doesn't exist results in a failure
# 2. test that sending a request to a software on a turned-off component results in a failure
# 3. test every implemented action under several different situation, some of which should lead to a success and some to a failure.
import pytest
from primaite.interface.request import RequestResponse
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
from primaite.simulator.network.hardware.nodes.host.host_node import HostNode
from primaite.simulator.network.hardware.nodes.network.router import ACLAction, Router
from primaite.simulator.network.transmission.transport_layer import Port
from tests.conftest import TestApplication, TestService
def test_successful_application_requests(example_network):
net = example_network
client_1 = net.get_node_by_hostname("client_1")
client_1.software_manager.install(TestApplication)
client_1.software_manager.software.get("TestApplication").run()
resp_1 = net.apply_request(["node", "client_1", "application", "TestApplication", "scan"])
assert resp_1 == RequestResponse(status="success", data={})
resp_2 = net.apply_request(["node", "client_1", "application", "TestApplication", "patch"])
assert resp_2 == RequestResponse(status="success", data={})
resp_3 = net.apply_request(["node", "client_1", "application", "TestApplication", "compromise"])
assert resp_3 == RequestResponse(status="success", data={})
def test_successful_service_requests(example_network):
net = example_network
server_1 = net.get_node_by_hostname("server_1")
server_1.software_manager.install(TestService)
# Careful: the order here is important, for example we cannot run "stop" unless we run "start" first
for verb in [
"disable",
"enable",
"start",
"stop",
"start",
"restart",
"pause",
"resume",
"compromise",
"scan",
"patch",
]:
resp_1 = net.apply_request(["node", "server_1", "service", "TestService", verb])
assert resp_1 == RequestResponse(status="success", data={})
server_1.apply_timestep(timestep=1)
server_1.apply_timestep(timestep=1)
server_1.apply_timestep(timestep=1)
server_1.apply_timestep(timestep=1)
server_1.apply_timestep(timestep=1)
server_1.apply_timestep(timestep=1)
server_1.apply_timestep(timestep=1)
# lazily apply timestep 7 times to make absolutely sure any time-based things like restart have a chance to finish
def test_non_existent_requests(example_network):
net = example_network
resp_1 = net.apply_request(["fake"])
assert resp_1.status == "unreachable"
resp_2 = net.apply_request(["network", "node", "client_39", "application", "WebBrowser", "execute"])
assert resp_2.status == "unreachable"
@pytest.mark.parametrize(
"node_request",
[
["node", "client_1", "file_system", "folder", "root", "scan"],
["node", "client_1", "os", "scan"],
["node", "client_1", "service", "DNSClient", "stop"],
["node", "client_1", "application", "WebBrowser", "scan"],
["node", "client_1", "network_interface", 1, "disable"],
],
)
def test_request_fails_if_node_off(example_network, node_request):
"""Test that requests succeed when the node is on, and fail if the node is off."""
net = example_network
client_1: HostNode = net.get_node_by_hostname("client_1")
client_1.shut_down_duration = 0
assert client_1.operating_state == NodeOperatingState.ON
resp_1 = net.apply_request(node_request)
assert resp_1.status == "success"
client_1.power_off()
assert client_1.operating_state == NodeOperatingState.OFF
resp_2 = net.apply_request(node_request)
assert resp_2.status == "failure"
class TestDataManipulationGreenRequests:
def test_node_off(self, uc2_network):
"""Test that green requests succeed when the node is on and fail if the node is off."""
net = uc2_network
client_1_browser_execute = net.apply_request(["node", "client_1", "application", "WebBrowser", "execute"])
client_1_db_client_execute = net.apply_request(["node", "client_1", "application", "DatabaseClient", "execute"])
client_2_browser_execute = net.apply_request(["node", "client_2", "application", "WebBrowser", "execute"])
client_2_db_client_execute = net.apply_request(["node", "client_2", "application", "DatabaseClient", "execute"])
assert client_1_browser_execute.status == "success"
assert client_1_db_client_execute.status == "success"
assert client_2_browser_execute.status == "success"
assert client_2_db_client_execute.status == "success"
client_1 = net.get_node_by_hostname("client_1")
client_2 = net.get_node_by_hostname("client_2")
client_1.shut_down_duration = 0
client_1.power_off()
client_2.shut_down_duration = 0
client_2.power_off()
client_1_browser_execute_off = net.apply_request(["node", "client_1", "application", "WebBrowser", "execute"])
client_1_db_client_execute_off = net.apply_request(
["node", "client_1", "application", "DatabaseClient", "execute"]
)
client_2_browser_execute_off = net.apply_request(["node", "client_2", "application", "WebBrowser", "execute"])
client_2_db_client_execute_off = net.apply_request(
["node", "client_2", "application", "DatabaseClient", "execute"]
)
assert client_1_browser_execute_off.status == "failure"
assert client_1_db_client_execute_off.status == "failure"
assert client_2_browser_execute_off.status == "failure"
assert client_2_db_client_execute_off.status == "failure"
def test_acl_block(self, uc2_network):
"""Test that green requests succeed when not blocked by ACLs but fail when blocked."""
net = uc2_network
router: Router = net.get_node_by_hostname("router_1")
client_1: HostNode = net.get_node_by_hostname("client_1")
client_2: HostNode = net.get_node_by_hostname("client_2")
client_1_browser_execute = net.apply_request(["node", "client_1", "application", "WebBrowser", "execute"])
client_2_browser_execute = net.apply_request(["node", "client_2", "application", "WebBrowser", "execute"])
assert client_1_browser_execute.status == "success"
assert client_2_browser_execute.status == "success"
router.acl.add_rule(ACLAction.DENY, src_port=Port.HTTP, dst_port=Port.HTTP, position=3)
client_1_browser_execute = net.apply_request(["node", "client_1", "application", "WebBrowser", "execute"])
client_2_browser_execute = net.apply_request(["node", "client_2", "application", "WebBrowser", "execute"])
assert client_1_browser_execute.status == "failure"
assert client_2_browser_execute.status == "failure"
client_1_db_client_execute = net.apply_request(["node", "client_1", "application", "DatabaseClient", "execute"])
client_2_db_client_execute = net.apply_request(["node", "client_2", "application", "DatabaseClient", "execute"])
assert client_1_db_client_execute.status == "success"
assert client_2_db_client_execute.status == "success"
router.acl.add_rule(ACLAction.DENY, src_port=Port.POSTGRES_SERVER, dst_port=Port.POSTGRES_SERVER)
client_1_db_client_execute = net.apply_request(["node", "client_1", "application", "DatabaseClient", "execute"])
client_2_db_client_execute = net.apply_request(["node", "client_2", "application", "DatabaseClient", "execute"])
assert client_1_db_client_execute.status == "failure"
assert client_2_db_client_execute.status == "failure"