diff --git a/modules/test/base/python/src/test_module.py b/modules/test/base/python/src/test_module.py index 8bee611b9..519fb2433 100644 --- a/modules/test/base/python/src/test_module.py +++ b/modules/test/base/python/src/test_module.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """Base class for all core test module functions""" import json import logger @@ -102,11 +101,26 @@ def run_tests(self): else: if result[0] is None: test['result'] = 'skipped' + if len(result)>1: + test['result_details'] = result[1] else: test['result'] = 'compliant' if result[0] else 'non-compliant' test['result_details'] = result[1] else: test['result'] = 'skipped' + + # Generate the short result description based on result value + if test['result'] == 'compliant': + test['result_description'] = test[ + 'short_description'] if 'short_description' in test else test[ + 'name'] + ' passed - see result details for more info' + elif test['result'] == 'non-compliant': + test['result_description'] = test[ + 'name'] + ' failed - see result details for more info' + else: + test['result_description'] = test[ + 'name'] + ' skipped - see result details for more info' + test['end'] = datetime.now().isoformat() duration = datetime.fromisoformat(test['end']) - datetime.fromisoformat( test['start']) diff --git a/modules/test/baseline/conf/module_config.json b/modules/test/baseline/conf/module_config.json index 4c0cd08d8..f4daf0e36 100644 --- a/modules/test/baseline/conf/module_config.json +++ b/modules/test/baseline/conf/module_config.json @@ -15,17 +15,20 @@ { "name": "baseline.pass", "description": "Simulate a compliant test", - "expected_behavior": "A compliant test result is generated" + "expected_behavior": "A compliant test result is generated", + "short_description": "A compliant test result is generated" }, { "name": "baseline.fail", "description": "Simulate a non-compliant test", - "expected_behavior": "A non-compliant test result is generated" + "expected_behavior": "A non-compliant test result is generated", + "short_description": "A non-compliant test result is generated" }, { "name": "baseline.skip", "description": "Simulate a skipped test", - "expected_behavior": "A skipped test result is generated" + "expected_behavior": "A skipped test result is generated", + "short_description": "A skipped test result is generated" } ] } diff --git a/modules/test/baseline/python/src/baseline_module.py b/modules/test/baseline/python/src/baseline_module.py index 22555d369..978f916fe 100644 --- a/modules/test/baseline/python/src/baseline_module.py +++ b/modules/test/baseline/python/src/baseline_module.py @@ -15,7 +15,7 @@ """Baseline test module""" from test_module import TestModule -LOG_NAME = "test_baseline" +LOG_NAME = 'test_baseline' LOGGER = None @@ -28,15 +28,16 @@ def __init__(self, module): LOGGER = self._get_logger() def _baseline_pass(self): - LOGGER.info("Running baseline pass test") - LOGGER.info("Baseline pass test finished") - return True + LOGGER.info('Running baseline pass test') + LOGGER.info('Baseline pass test finished') + return True, 'Baseline pass test ran successfully' def _baseline_fail(self): - LOGGER.info("Running baseline pass test") - LOGGER.info("Baseline pass test finished") - return False + LOGGER.info('Running baseline fail test') + LOGGER.info('Baseline fail test finished') + return False, 'Baseline fail test ran successfully' def _baseline_skip(self): - LOGGER.info("Running baseline pass test") - LOGGER.info("Baseline pass test finished") + LOGGER.info('Running baseline skip test') + LOGGER.info('Baseline skip test finished') + return None, 'Baseline skip test ran successfully' diff --git a/modules/test/conn/conf/module_config.json b/modules/test/conn/conf/module_config.json index 3e06cc891..860b04e0b 100644 --- a/modules/test/conn/conf/module_config.json +++ b/modules/test/conn/conf/module_config.json @@ -6,31 +6,48 @@ "description": "Connection tests" }, "network": true, + "interface_control": true, "docker": { "depends_on": "base", "enable_container": true, "timeout": 600 }, "tests": [ + { + "name": "connection.dhcp.disconnect", + "description": "The device under test has received an IP address from the DHCP server and responds to an ICMP echo (ping) request", + "expected_behavior": "The device is not setup with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds succesfully to an ICMP echo (ping) request.", + "short_description": "Device has received an IP address after port disconnect" + }, + { + "name": "connection.dhcp.disconnect_ip_change", + "description": "Update device IP on the DHCP server and reconnect the device. Does the device receive the new IP address?", + "expected_behavior": "Device recieves a new IP address within the range that is specified on the DHCP server. Device should respond to aping on this new address.", + "short_description": "Device has received new IP address after port disconnect" + }, { "name": "connection.dhcp_address", "description": "The device under test has received an IP address from the DHCP server and responds to an ICMP echo (ping) request", - "expected_behavior": "The device is not setup with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds succesfully to an ICMP echo (ping) request." + "expected_behavior": "The device is not setup with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds succesfully to an ICMP echo (ping) request.", + "short_description": "Device has received a DHCP provided IP address" }, { "name": "connection.mac_address", "description": "Check and note device physical address.", - "expected_behavior": "N/A" + "expected_behavior": "N/A", + "short_description": "Device MAC address resolved" }, { "name": "connection.mac_oui", "description": "The device under test hs a MAC address prefix that is registered against a known manufacturer.", - "expected_behavior": "The MAC address prefix is registered in the IEEE Organizationally Unique Identifier database." + "expected_behavior": "The MAC address prefix is registered in the IEEE Organizationally Unique Identifier database.", + "short_description": "OUI for MAC address resolved" }, { "name": "connection.private_address", "description": "The device under test accepts an IP address that is compliant with RFC 1918 Address Allocation for Private Internets.", "expected_behavior": "The device under test accepts IP addresses within all ranges specified in RFC 1918 and communicates using these addresses. The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets. 10.0.0.0 - 10.255.255.255.255 (10/8 prefix). 172.16.0.0 - 172.31.255.255 (172.16/12 prefix). 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)", + "short_description": "Device supports private addresses", "config": { "ranges": [ { @@ -52,6 +69,7 @@ "name": "connection.shared_address", "description": "Ensure the device supports RFC 6598 IANA-Reserved IPv4 Prefix for Shared Address Space", "expected_behavior": "The device under test accepts IP addresses within the ranges specified in RFC 6598 and communicates using these addresses", + "short_description": "Device supports shared address space", "config": { "ranges": [ { @@ -64,32 +82,38 @@ { "name": "connection.single_ip", "description": "The network switch port connected to the device reports only one IP address for the device under test.", - "expected_behavior": "The device under test does not behave as a network switch and only requets one IP address. This test is to avoid that devices implement network switches that allow connecting strings of daisy chained devices to one single network port, as this would not make 802.1x port based authentication possible." + "expected_behavior": "The device under test does not behave as a network switch and only requets one IP address. This test is to avoid that devices implement network switches that allow connecting strings of daisy chained devices to one single network port, as this would not make 802.1x port based authentication possible.", + "short_description": "Device only reports one IP address" }, { "name": "connection.target_ping", "description": "The device under test responds to an ICMP echo (ping) request.", - "expected_behavior": "The device under test responds to an ICMP echo (ping) request." + "expected_behavior": "The device under test responds to an ICMP echo (ping) request.", + "short_description": "Device responds to a ping request" }, { "name": "connection.ipaddr.ip_change", - "description": "The device responds to a ping (ICMP echo request) to the new IP address it has received after the initial dHCP lease has expired.", - "expected_behavior": "If the lease expires before the client receiveds a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requires network initialization parameters as if the client were uninitialized. If the client then receives a DHCPACK allocating the client its previous network addres, the client SHOULD continue network processing. If the client is given a new network address, it MUST NOT continue using the previous network address and SHOULD notify the local users of the problem." + "description": "The device responds to a ping (ICMP echo request) to the new IP address it has received after the initial DHCP lease has expired.", + "expected_behavior": "If the lease expires before the client receiveds a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requires network initialization parameters as if the client were uninitialized. If the client then receives a DHCPACK allocating the client its previous network addres, the client SHOULD continue network processing. If the client is given a new network address, it MUST NOT continue using the previous network address and SHOULD notify the local users of the problem.", + "short_description": "Device receives an IP change from the DHCP server" }, { "name": "connection.ipaddr.dhcp_failover", "description": "The device has requested a DHCPREQUEST/REBIND to the DHCP failover server after the primary DHCP server has been brought down.", - "expected_behavior": "" + "expected_behavior": "", + "short_description": "Device receives IP address from primary and failover DHCP servers" }, { "name": "connection.ipv6_slaac", "description": "The device forms a valid IPv6 address as a combination of the IPv6 router prefix and the device interface identifier", - "expected_behavior": "The device under test complies with RFC4862 and forms a valid IPv6 SLAAC address" + "expected_behavior": "The device under test complies with RFC4862 and forms a valid IPv6 SLAAC address", + "short_description": "Device uses an IPv6 address using SLAAC" }, { "name": "connection.ipv6_ping", "description": "The device responds to an IPv6 ping (ICMPv6 Echo) request to the SLAAC address", - "expected_behavior": "The device responds to the ping as per RFC4443" + "expected_behavior": "The device responds to the ping as per RFC4443", + "short_description": "Device responds to an IPv6 SLAAC address ping request" } ] } diff --git a/modules/test/conn/python/requirements.txt b/modules/test/conn/python/requirements.txt index 2b8d18750..c523787b9 100644 --- a/modules/test/conn/python/requirements.txt +++ b/modules/test/conn/python/requirements.txt @@ -1 +1,2 @@ -pyOpenSSL \ No newline at end of file +pyOpenSSL +scapy \ No newline at end of file diff --git a/modules/test/conn/python/src/connection_module.py b/modules/test/conn/python/src/connection_module.py index 169fb98c3..248edc536 100644 --- a/modules/test/conn/python/src/connection_module.py +++ b/modules/test/conn/python/src/connection_module.py @@ -253,6 +253,7 @@ def _get_oui_manufacturer(self, mac_address): def _connection_ipv6_slaac(self): LOGGER.info('Running connection.ipv6_slaac') + result = None packet_capture = rdpcap(MONITOR_CAPTURE_FILE) sends_ipv6 = False @@ -265,27 +266,31 @@ def _connection_ipv6_slaac(self): if ipv6_addr.startswith(SLAAC_PREFIX): self._device_ipv6_addr = ipv6_addr LOGGER.info(f'Device has formed SLAAC address {ipv6_addr}') - return True - - if sends_ipv6: - LOGGER.info('Device does not support IPv6 SLAAC') - else: - LOGGER.info('Device does not support IPv6') - return False + result = True, f'Device has formed SLAAC address {ipv6_addr}' + if result is None: + if sends_ipv6: + LOGGER.info('Device does not support IPv6 SLAAC') + result = False, 'Device does not support IPv6 SLAAC' + else: + LOGGER.info('Device does not support IPv6') + result = False, 'Device does not support IPv6' + return result def _connection_ipv6_ping(self): LOGGER.info('Running connection.ipv6_ping') - + result = None + if self._device_ipv6_addr is None: LOGGER.info('No IPv6 SLAAC address found. Cannot ping') - return - - if self._ping(self._device_ipv6_addr): - LOGGER.info(f'Device responds to IPv6 ping on {self._device_ipv6_addr}') - return True + result = None, 'No IPv6 SLAAc address found. Cannot ping' else: - LOGGER.info('Device does not respond to IPv6 ping') - return False + if self._ping(self._device_ipv6_addr): + LOGGER.info(f'Device responds to IPv6 ping on {self._device_ipv6_addr}') + result = True, f'Device responds to IPv6 ping on {self._device_ipv6_addr}' + else: + LOGGER.info('Device does not respond to IPv6 ping') + result = False, 'Device does not respond to IPv6 ping' + return result def _ping(self, host): cmd = 'ping -c 1 ' + str(host) diff --git a/modules/test/dns/conf/module_config.json b/modules/test/dns/conf/module_config.json index 177537b69..b5e3c8420 100644 --- a/modules/test/dns/conf/module_config.json +++ b/modules/test/dns/conf/module_config.json @@ -15,16 +15,19 @@ { "name": "dns.network.from_device", "description": "Verify the device sends DNS requests", - "expected_behavior": "The device sends DNS requests." + "expected_behavior": "The device sends DNS requests.", + "short_description": "The device sends DNS requests." }, { "name": "dns.network.from_dhcp", "description": "Verify the device allows for a DNS server to be entered automatically", - "expected_behavior": "The device sends DNS requests to the DNS server provided by the DHCP server" + "expected_behavior": "The device sends DNS requests to the DNS server provided by the DHCP server", + "short_description": "The device sends DNS requests to local DNS server." }, { "name": "dns.mdns", - "description": "If the device has MDNS (or any kind of IP multicast), can it be disabled" + "description": "If the device has MDNS (or any kind of IP multicast), can it be disabled", + "short_description": "MDNS traffic detected from device" } ] } diff --git a/modules/test/dns/python/src/dns_module.py b/modules/test/dns/python/src/dns_module.py index aecbd5bd1..bc56c3718 100644 --- a/modules/test/dns/python/src/dns_module.py +++ b/modules/test/dns/python/src/dns_module.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """DNS test module""" import subprocess from test_module import TestModule @@ -32,60 +31,84 @@ def __init__(self, module): global LOGGER LOGGER = self._get_logger() - def _check_dns_traffic(self, tcpdump_filter): - dns_server_queries = self._exec_tcpdump(tcpdump_filter,DNS_SERVER_CAPTURE_FILE) + def _has_dns_traffic(self, tcpdump_filter): + dns_server_queries = self._exec_tcpdump(tcpdump_filter, + DNS_SERVER_CAPTURE_FILE) LOGGER.info('DNS Server queries found: ' + str(len(dns_server_queries))) - dns_startup_queries = self._exec_tcpdump(tcpdump_filter,STARTUP_CAPTURE_FILE) + dns_startup_queries = self._exec_tcpdump(tcpdump_filter, + STARTUP_CAPTURE_FILE) LOGGER.info('Startup DNS queries found: ' + str(len(dns_startup_queries))) - dns_monitor_queries = self._exec_tcpdump(tcpdump_filter,MONITOR_CAPTURE_FILE) + dns_monitor_queries = self._exec_tcpdump(tcpdump_filter, + MONITOR_CAPTURE_FILE) LOGGER.info('Monitor DNS queries found: ' + str(len(dns_monitor_queries))) - num_query_dns = len(dns_server_queries) + len(dns_startup_queries) + len(dns_monitor_queries) - + num_query_dns = len(dns_server_queries) + len(dns_startup_queries) + len( + dns_monitor_queries) LOGGER.info('DNS queries found: ' + str(num_query_dns)) - dns_traffic_detected = num_query_dns > 0 - LOGGER.info('DNS traffic detected: ' + str(dns_traffic_detected)) - return dns_traffic_detected + + return num_query_dns > 0 def _dns_network_from_dhcp(self): - LOGGER.info("Running dns.network.from_dhcp") + LOGGER.info('Running dns.network.from_dhcp') + result = None LOGGER.info('Checking DNS traffic for configured DHCP DNS server: ' + self._dns_server) - # Check if the device DNS traffic is to appropriate server - tcpdump_filter = f'dst port 53 and dst host {self._dns_server} and ether src {self._device_mac}' - - result = self._check_dns_traffic(tcpdump_filter=tcpdump_filter) - - LOGGER.info('DNS traffic detected to configured DHCP DNS server: ' + - str(result)) + # Check if the device DNS traffic is to appropriate local + # DHCP provided server + tcpdump_filter = (f'dst port 53 and dst host {self._dns_server} ' + + 'and ether src {self._device_mac}') + dns_packets_local = self._has_dns_traffic(tcpdump_filter=tcpdump_filter) + + # Check if the device sends any DNS traffic to non-DHCP provided server + tcpdump_filter = (f'dst port 53 and dst not host {self._dns_server} ' + + 'ether src {self._device_mac}') + dns_packets_not_local = self._has_dns_traffic(tcpdump_filter=tcpdump_filter) + + if dns_packets_local or dns_packets_not_local: + if dns_packets_not_local: + result = False, 'DNS traffic detected to non-DHCP provided server' + else: + LOGGER.info('DNS traffic detected only to configured DHCP DNS server') + result = True, 'DNS traffic detected only to DHCP provided server' + else: + LOGGER.info('No DNS traffic detected from the device') + result = None, 'No DNS traffic detected from the device' return result def _dns_network_from_device(self): - LOGGER.info("Running dns.network.from_device") + LOGGER.info('Running dns.network.from_device') + result = None LOGGER.info('Checking DNS traffic from device: ' + self._device_mac) - # Check if the device DNS traffic is to appropriate server + # Check if the device DNS traffic tcpdump_filter = f'dst port 53 and ether src {self._device_mac}' - - result = self._check_dns_traffic(tcpdump_filter=tcpdump_filter) - - LOGGER.info('DNS traffic detected from device: ' + str(result)) + dns_packetes = self._has_dns_traffic(tcpdump_filter=tcpdump_filter) + + if dns_packetes: + LOGGER.info('DNS traffic detected from device') + result = True, 'DNS traffic detected from device' + else: + LOGGER.info('No DNS traffic detected from the device') + result = False, 'No DNS traffic detected from the device' return result def _dns_mdns(self): - LOGGER.info("Running dns.mdns") - + LOGGER.info('Running dns.mdns') + result = None # Check if the device sends any MDNS traffic tcpdump_filter = f'udp port 5353 and ether src {self._device_mac}' - - result = self._check_dns_traffic(tcpdump_filter=tcpdump_filter) - - LOGGER.info('MDNS traffic detected from device: ' + str(result)) - return not result - + dns_packetes = self._has_dns_traffic(tcpdump_filter=tcpdump_filter) + + if dns_packetes: + LOGGER.info('MDNS traffic detected from device') + result = True, 'MDNS traffic detected from device' + else: + LOGGER.info('No MDNS traffic detected from the device') + result = None, 'No MDNS traffic detected from the device' + return result def _exec_tcpdump(self, tcpdump_filter, capture_file): """ diff --git a/modules/test/nmap/conf/module_config.json b/modules/test/nmap/conf/module_config.json index 292eced8b..b03e9511c 100644 --- a/modules/test/nmap/conf/module_config.json +++ b/modules/test/nmap/conf/module_config.json @@ -16,6 +16,7 @@ "name": "security.nmap.ports", "description": "Run an nmap scan of open ports", "expected_behavior": "Report all open ports", + "short_description": "NMAP scan reports no unallowed ports open", "config": { "security.services.ftp": { "tcp_ports": { diff --git a/modules/test/nmap/python/src/nmap_module.py b/modules/test/nmap/python/src/nmap_module.py index f998f302a..6bcbd141a 100644 --- a/modules/test/nmap/python/src/nmap_module.py +++ b/modules/test/nmap/python/src/nmap_module.py @@ -40,6 +40,7 @@ def __init__(self, module): def _security_nmap_ports(self, config): LOGGER.info("Running security.nmap.ports test") + result = None # Delete the enabled key from the config if it exists # to prevent it being treated as a test key @@ -74,10 +75,14 @@ def _security_nmap_ports(self, config): LOGGER.info("Unallowed Ports Detected: " + str(self._unallowed_ports)) self._check_unallowed_port(self._unallowed_ports,config) LOGGER.info("Unallowed Ports: " + str(self._unallowed_ports)) - return len(self._unallowed_ports) == 0 + if len(self._unallowed_ports) > 0: + result = False, 'Some allowed ports detected: ' + str(self._unallowed_ports) + else: + result = True, 'No unallowed ports detected' else: LOGGER.info("Device ip address not resolved, skipping") - return None + result = None, "Device ip address not resolved" + return result def _process_port_results(self, tests): scan_results = {} diff --git a/modules/test/nmap/python/src/run.py b/modules/test/nmap/python/src/run.py index 5e33451d9..e68b52525 100644 --- a/modules/test/nmap/python/src/run.py +++ b/modules/test/nmap/python/src/run.py @@ -20,7 +20,7 @@ from nmap_module import NmapModule -LOG_NAME = "nmap_runner" +LOG_NAME = 'nmap_runner' LOGGER = logger.get_logger(LOG_NAME) class NmapModuleRunner: @@ -39,7 +39,7 @@ def __init__(self, module): self._test_module = NmapModule(module) self._test_module.run_tests() - LOGGER.info("nmap test module finished") + LOGGER.info('nmap test module finished') def add_logger(self, module): global LOGGER diff --git a/modules/test/ntp/conf/module_config.json b/modules/test/ntp/conf/module_config.json index 288474868..c20d2067b 100644 --- a/modules/test/ntp/conf/module_config.json +++ b/modules/test/ntp/conf/module_config.json @@ -15,12 +15,14 @@ { "name": "ntp.network.ntp_support", "description": "Does the device request network time sync as client as per RFC 5905 - Network Time Protocol Version 4: Protocol and Algorithms Specification", - "expected_behavior": "The device sends an NTPv4 request to the configured NTP server." + "expected_behavior": "The device sends an NTPv4 request to the configured NTP server.", + "short_description": "The device sends NTPv4 requests" }, { "name": "ntp.network.ntp_dhcp", "description": "Accept NTP address over DHCP", - "expected_behavior": "Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)" + "expected_behavior": "Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)", + "short_descriiption": "Accepts NTP address over DHCP" } ] } diff --git a/modules/test/ntp/python/src/ntp_module.py b/modules/test/ntp/python/src/ntp_module.py index 4053ce98a..6a577d1a6 100644 --- a/modules/test/ntp/python/src/ntp_module.py +++ b/modules/test/ntp/python/src/ntp_module.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """NTP test module""" from test_module import TestModule from scapy.all import rdpcap, NTP, IP @@ -22,6 +21,7 @@ MONITOR_CAPTURE_FILE = '/runtime/device/monitor.pcap' LOGGER = None + class NTPModule(TestModule): """NTP Test module""" @@ -35,7 +35,7 @@ def __init__(self, module): def _ntp_network_ntp_support(self): LOGGER.info('Running ntp.network.ntp_support') - + result = None packet_capture = rdpcap(STARTUP_CAPTURE_FILE) + rdpcap(MONITOR_CAPTURE_FILE) device_sends_ntp4 = False @@ -52,28 +52,47 @@ def _ntp_network_ntp_support(self): LOGGER.info(f'Device sent NTPv3 request to {packet[IP].dst}') if not (device_sends_ntp3 or device_sends_ntp4): - LOGGER.info('Device has not sent any NTP requests') - - return device_sends_ntp4 and not device_sends_ntp3 + result = False, 'Device has not sent any NTP requests' + elif device_sends_ntp3 and device_sends_ntp4: + result = False, ('Device sent NTPv3 and NTPv4 packets. ' + + 'NTPv3 is not allowed.') + elif device_sends_ntp3: + result = False, ('Device sent NTPv3 packets. ' + 'NTPv3 is not allowed.') + elif device_sends_ntp4: + result = True, 'Device sent NTPv4 packets.' + LOGGER.info(result[1]) + return result def _ntp_network_ntp_dhcp(self): LOGGER.info('Running ntp.network.ntp_dhcp') - + result = None packet_capture = rdpcap(STARTUP_CAPTURE_FILE) + rdpcap(MONITOR_CAPTURE_FILE) device_sends_ntp = False + ntp_to_local = False + ntp_to_remote = False for packet in packet_capture: - if NTP in packet and packet.src == self._device_mac: device_sends_ntp = True if packet[IP].dst == self._ntp_server: LOGGER.info('Device sent NTP request to DHCP provided NTP server') - return True - - if not device_sends_ntp: - LOGGER.info('Device has not sent any NTP requests') + ntp_to_local = True + else: + LOGGER.info('Device sent NTP request to non-DHCP provided NTP server') + ntp_to_remote = True + + if device_sends_ntp: + if ntp_to_local and ntp_to_remote: + result = False, ('Device sent NTP request to DHCP provided ' + + 'server and non-DHCP provided server') + elif ntp_to_remote: + result = False, 'Device sent NTP request to non-DHCP provided server' + elif ntp_to_local: + result = True, 'Device sent NTP request to DHCP provided server' else: - LOGGER.info('Device has not sent NTP requests to DHCP provided NTP server') + result = False, 'Device has not sent any NTP requests' - return False + LOGGER.info(result[1]) + return result diff --git a/modules/test/tls/conf/module_config.json b/modules/test/tls/conf/module_config.json index 59e5a839d..f71f39914 100644 --- a/modules/test/tls/conf/module_config.json +++ b/modules/test/tls/conf/module_config.json @@ -15,22 +15,26 @@ { "name": "security.tls.v1_2_server", "description": "Check the device web server TLS 1.2 & certificate is valid", - "expected_behavior": "TLS 1.2 certificate is issued to the web browser client when accessed" + "expected_behavior": "TLS 1.2 certificate is issued to the web browser client when accessed", + "short_description": "TLS 1.2 server certificate is valid" }, { "name": "security.tls.v1_3_server", "description": "Check the device web server TLS 1.3 & certificate is valid", - "expected_behavior": "TLS 1.3 certificate is issued to the web browser client when accessed" + "expected_behavior": "TLS 1.3 certificate is issued to the web browser client when accessed", + "short_description": "TLS 1.3 server certificate is valid" }, { "name": "security.tls.v1_2_client", "description": "Device uses TLS with connection to an external service on port 443 (or any other port which could be running the webserver-HTTPS)", - "expected_behavior": "The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers" + "expected_behavior": "The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers", + "short_description": "TLS 1.2 outbound connection valid" }, { "name": "security.tls.v1_3_client", "description": "Device uses TLS with connection to an external service on port 443 (or any other port which could be running the webserver-HTTPS)", - "expected_behavior": "The packet indicates a TLS connection with at least TLS 1.3" + "expected_behavior": "The packet indicates a TLS connection with at least TLS 1.3", + "short_description": "TLS 1.3 outbound connection valid" } ] } diff --git a/modules/test/tls/python/src/tls_module_test.py b/modules/test/tls/python/src/tls_module_test.py index 84a1c70eb..099956f4e 100644 --- a/modules/test/tls/python/src/tls_module_test.py +++ b/modules/test/tls/python/src/tls_module_test.py @@ -31,6 +31,7 @@ class TLSModuleTest(unittest.TestCase): """Contains and runs all the unit tests concerning TLS behaviors""" + @classmethod def setUpClass(cls): log = logger.get_logger(MODULE_NAME) @@ -129,13 +130,29 @@ def security_tls_v1_3_client_test(self): self.assertTrue(test_results[0]) def client_hello_packets_test(self): - packet_fail = {'dst_ip': '10.10.10.1', 'src_ip': '10.10.10.14', 'dst_port': '443', 'cipher_support': {'ecdh': False, 'ecdsa': True}} - packet_success = {'dst_ip': '10.10.10.1', 'src_ip': '10.10.10.14', 'dst_port': '443', 'cipher_support': {'ecdh': True, 'ecdsa': True}} - hello_packets = [packet_fail,packet_success] - hello_results = TLS_UTIL.process_hello_packets(hello_packets,'1.2') - print("Hello packets test results: " + str(hello_results)) - expected = {'valid':[packet_success],'invalid':[]} - self.assertEqual(hello_results,expected) + packet_fail = { + 'dst_ip': '10.10.10.1', + 'src_ip': '10.10.10.14', + 'dst_port': '443', + 'cipher_support': { + 'ecdh': False, + 'ecdsa': True + } + } + packet_success = { + 'dst_ip': '10.10.10.1', + 'src_ip': '10.10.10.14', + 'dst_port': '443', + 'cipher_support': { + 'ecdh': True, + 'ecdsa': True + } + } + hello_packets = [packet_fail, packet_success] + hello_results = TLS_UTIL.process_hello_packets(hello_packets, '1.2') + print('Hello packets test results: ' + str(hello_results)) + expected = {'valid': [packet_success], 'invalid': []} + self.assertEqual(hello_results, expected) def test_client_tls(self, tls_version,