Esempio n. 1
0
    def _evaluate_negative_response_code(
        self,
        state,  # type: EcuState
        response,  # type: Packet
        **kwargs  # type: Optional[Dict[str, Any]]  # noqa: E501
    ):  # type: (...) -> bool
        exit_if_service_not_supported = \
            kwargs.pop("exit_if_service_not_supported", False)
        exit_scan_on_first_negative_response = \
            kwargs.pop("exit_scan_on_first_negative_response", False)

        if exit_scan_on_first_negative_response and response.service == 0x7f:
            return True

        if exit_if_service_not_supported and response.service == 0x7f:
            response_code = self._get_negative_response_code(response)
            if response_code in [0x11, 0x7f]:
                names = {
                    0x11: "serviceNotSupported",
                    0x7f: "serviceNotSupportedInActiveSession"
                }
                msg = "[-] Exit execute because negative response " \
                      "%s received!" % names[response_code]
                log_interactive.debug(msg)
                # execute of current state is completed,
                # since a serviceNotSupported negative response was received
                self._state_completed[state] = True
                # stop current execute and exit
                return True
        return False
Esempio n. 2
0
    def pre_execute(self,
                    socket,  # type: _SocketUnion
                    state,  # type: EcuState
                    global_configuration  # type: AutomotiveTestCaseExecutorConfiguration  # noqa: E501
                    ):  # type: (...) -> None
        test_case_cls = self.current_test_case.__class__
        try:
            self.__current_kwargs = global_configuration[
                test_case_cls.__name__]
        except KeyError:
            self.__current_kwargs = dict()
            global_configuration[test_case_cls.__name__] = \
                self.__current_kwargs

        if callable(self.current_connector) and self.__stage_index > 0:
            if self.previous_test_case:
                con = self.current_connector  # type: _TestCaseConnectorCallable  # noqa: E501
                con_kwargs = con(self.previous_test_case,
                                 self.current_test_case)
                if self.__current_kwargs is not None and con_kwargs is not None:  # noqa: E501
                    self.__current_kwargs.update(con_kwargs)

        log_interactive.debug("[i] Stage AutomotiveTestCase %s kwargs: %s",
                              self.current_test_case.__class__.__name__,
                              self.__current_kwargs)

        self.current_test_case.pre_execute(socket, state, global_configuration)
Esempio n. 3
0
    def get_new_edge(self, socket, config):
        # type: (_SocketUnion, AutomotiveTestCaseExecutorConfiguration) -> Optional[_Edge]  # noqa: E501
        last_resp = self._results[-1].resp
        last_state = self._results[-1].state

        if last_resp is None or last_resp.service == 0x7f:
            return None

        try:
            if last_resp.service != 0x67 or \
                    last_resp.securityAccessType % 2 != 1:
                return None

            seed = last_resp
            sec_lvl = seed.securityAccessType

            if self.get_security_access(socket, sec_lvl, seed):
                log_interactive.debug("Security Access found.")
                # create edge
                new_state = copy.copy(last_state)
                new_state.security_level = seed.securityAccessType + 1  # type: ignore  # noqa: E501
                if last_state == new_state:
                    return None
                edge = (last_state, new_state)
                self._transition_function_args[edge] = \
                    {"level": sec_lvl, "desc": "SA=%d" % sec_lvl}
                return edge
        except AttributeError:
            pass

        return None
Esempio n. 4
0
    def get_new_edge(self, socket, config):
        # type: (_SocketUnion, AutomotiveTestCaseExecutorConfiguration) -> Optional[_Edge]  # noqa: E501
        last_resp = self._results[-1].resp
        last_state = self._results[-1].state

        if last_resp is None or last_resp.service == 0x7f:
            return None

        try:
            if last_resp.service != 0x67 or \
                    last_resp.subfunction % 2 != 1:
                return None

            seed = last_resp
            sec_lvl = seed.subfunction
            kf = config[self.__class__.__name__].get("keyfunction", None)

            if self.get_security_access(socket,
                                        level=sec_lvl,
                                        seed_pkt=seed,
                                        keyfunction=kf):
                log_interactive.debug("Security Access found.")
                # create edge
                new_state = copy.copy(last_state)
                new_state.security_level = seed.subfunction + 1  # type: ignore  # noqa: E501
                if last_state == new_state:
                    return None
                edge = (last_state, new_state)
                self._transition_function_args[edge] = (sec_lvl, kf)
                return edge
        except AttributeError:
            pass

        return None
Esempio n. 5
0
    def scan(self, state, requests, timeout=1, **kwargs):

        if state not in self.request_iterators:
            self.request_iterators[state] = iter(requests)

        if self.retry_pkt:
            it = [self.retry_pkt]
        else:
            it = self.request_iterators[state]

        log_interactive.debug("Using iterator %s in state %s", it, state)

        for req in it:
            try:
                res = self.sock.sr1(req, timeout=timeout, verbose=False)
            except ValueError as e:
                warning("Exception in scan %s", e)
                break

            self.results.append(Enumerator.ScanResult(state, req, res))
            if self.evaluate_response(res, **kwargs):
                return

        self.update_stats()
        self.state_completed[state] = True
Esempio n. 6
0
 def cleanup(_, configuration):
     # type: (_SocketUnion, AutomotiveTestCaseExecutorConfiguration) -> bool
     try:
         configuration["tps"].stop()
         configuration["tps"] = None
     except (AttributeError, KeyError) as e:
         log_interactive.debug("Cleanup TP-Sender Error: %s", e)
     return True
Esempio n. 7
0
 def enter_diagnostic_session(socket):
     # type: (_SocketUnion) -> bool
     ans = socket.sr1(
         GMLAN() / GMLAN_IDO(subfunction=2), timeout=5, verbose=False)
     if ans is not None and ans.service == 0x7f:
         log_interactive.debug(
             "[-] InitiateDiagnosticOperation received negative response!\n"
             "%s", repr(ans))
     return ans is not None and ans.service != 0x7f
Esempio n. 8
0
 def _evaluate_ecu_state_modifications(self,
                                       state,  # type: EcuState
                                       request,  # type: Packet
                                       response,  # type: Packet
                                       ):  # type: (...) -> bool
     if EcuState.is_modifier_pkt(response):
         if state != EcuState.get_modified_ecu_state(
                 response, request, state):
             log_interactive.debug(
                 "[-] Exit execute. Ecu state was modified!")
             return True
     return False
Esempio n. 9
0
 def __get_retry_iterator(self, state):
     # type: (EcuState) -> Iterable[Packet]
     retry_entry = self._retry_pkt[state]
     if retry_entry is None:
         return []
     elif isinstance(retry_entry, Packet):
         log_interactive.debug("[i] Provide retry packet")
         return [retry_entry]
     else:
         log_interactive.debug("[i] Provide retry iterator")
         # assume self.retry_pkt is a generator or list
         return retry_entry
Esempio n. 10
0
 def enter_state(socket,  # type: _SocketUnion
                 configuration,  # type: AutomotiveTestCaseExecutorConfiguration  # noqa: E501
                 request  # type: Packet
                 ):  # type: (...) -> bool
     timeout = configuration[UDS_DSCEnumerator.__name__].get("timeout", 3)
     ans = socket.sr1(request, timeout=timeout, verbose=False)
     if ans is not None:
         if configuration.verbose:
             log_interactive.debug(
                 "Try to enter session req: %s, resp: %s" %
                 (repr(request), repr(ans)))
         return cast(int, ans.service) != 0x7f
     else:
         return False
Esempio n. 11
0
    def _evaluate_response(self,
                           state,  # type: EcuState
                           request,  # type: Packet
                           response,  # type: Optional[Packet]
                           **kwargs  # type: Optional[Dict[str, Any]]
                           ):  # type: (...) -> bool
        if super(GMLAN_SAEnumerator, self)._evaluate_response(
                state, request, response, **kwargs):
            return True

        if response is not None and \
                response.service == 0x67 and response.subfunction % 2 == 1:
            log_interactive.debug("[i] Seed received. Leave scan to try a key")
            return True
        return False
Esempio n. 12
0
    def reconnect(self):
        # type: () -> None
        if self.reconnect_handler:
            try:
                self.socket.close()
            except Exception as e:
                log_interactive.debug("[i] Exception '%s' during socket.close",
                                      e)

            log_interactive.info("[i] Target reconnect")
            socket = self.reconnect_handler()
            if not isinstance(socket, SingleConversationSocket):
                self.socket = SingleConversationSocket(socket)
            else:
                self.socket = socket
Esempio n. 13
0
    def _evaluate_retry(self,
                        state,  # type: EcuState
                        request,  # type: Packet
                        response,  # type: Packet
                        **kwargs  # type: Optional[Dict[str, Any]]
                        ):  # type: (...) -> bool
        retry_if_busy_returncode = \
            kwargs.pop("retry_if_busy_returncode", True)

        if retry_if_busy_returncode and response.service == 0x7f \
                and self._get_negative_response_code(response) == 0x21:
            log_interactive.debug(
                "[i] Retry %s because retry_if_busy_returncode received",
                repr(request))
            return self._populate_retry(state, request)
        return False
Esempio n. 14
0
    def execute(self, socket, state, **kwargs):
        # type: (_SocketUnion, EcuState, Any) -> None
        timeout = kwargs.pop('timeout', 1)
        execution_time = kwargs.pop("execution_time", 1200)

        it = self.__get_request_iterator(state, **kwargs)

        # log_interactive.debug("[i] Using iterator %s in state %s", it, state)

        start_time = time.time()
        log_interactive.debug("[i] Start execution of enumerator: %s",
                              time.ctime(start_time))

        for req in it:
            try:
                res = socket.sr1(req, timeout=timeout, verbose=False)
            except (OSError, ValueError, Scapy_Exception) as e:
                if self._retry_pkt[state] is None:
                    log_interactive.debug(
                        "[-] Exception '%s' in execute. Prepare for retry", e)
                    self._retry_pkt[state] = req
                else:
                    log_interactive.critical(
                        "[-] Exception during retry. This is bad")
                raise e

            if socket.closed:
                log_interactive.critical("[-] Socket closed during scan.")
                return

            self._store_result(state, req, res)

            if self._evaluate_response(state, req, res, **kwargs):
                log_interactive.debug("[i] Stop test_case execution because "
                                      "of response evaluation")
                return

            if (start_time + execution_time) < time.time():
                log_interactive.debug(
                    "[i] Finished execution time of enumerator: %s",
                    time.ctime())
                return

        log_interactive.info("[i] Finished iterator execution")
        self._state_completed[state] = True
        log_interactive.debug("[i] States completed %s",
                              repr(self._state_completed))
Esempio n. 15
0
    def _get_initial_requests(self, **kwargs):
        # type: (Any) -> Iterable[Packet]
        scan_range = kwargs.pop("scan_range", range(0x10000))
        rdbi_enumerator = kwargs.pop("rdbi_enumerator", None)

        if rdbi_enumerator is None:
            log_interactive.debug("[i] Use entire scan range")
            return (UDS() / UDS_WDBI(dataIdentifier=x) for x in scan_range)
        elif isinstance(rdbi_enumerator, UDS_RDBIEnumerator):
            log_interactive.debug("[i] Selective scan based on RDBI results")
            return (UDS() / UDS_WDBI(dataIdentifier=t.resp.dataIdentifier) /
                    Raw(load=bytes(t.resp)[3:])
                    for t in rdbi_enumerator.results_with_positive_response
                    if len(bytes(t.resp)) >= 3)
        else:
            raise Scapy_Exception("rdbi_enumerator has to be an instance "
                                  "of UDS_RDBIEnumerator")
Esempio n. 16
0
    def __init__(self, test_cases, **kwargs):
        # type: (Union[List[Union[AutomotiveTestCaseABC, Type[AutomotiveTestCaseABC]]], List[Type[AutomotiveTestCaseABC]]], Any) -> None  # noqa: E501
        self.verbose = kwargs.get("verbose", False)
        self.debug = kwargs.get("debug", False)
        self.unittest = kwargs.pop("unittest", False)
        self.state_graph = Graph()
        self.test_cases = list()  # type: List[AutomotiveTestCaseABC]
        self.stages = list()  # type: List[StagedAutomotiveTestCase]
        self.staged_test_cases = list()  # type: List[AutomotiveTestCaseABC]
        self.test_case_clss = set()  # type: Set[Type[AutomotiveTestCaseABC]]
        self.global_kwargs = kwargs

        for tc in test_cases:
            self.add_test_case(tc)

        log_interactive.debug("The following configuration was created")
        log_interactive.debug(self.__dict__)
Esempio n. 17
0
    def __init__(self, socket, reset_handler=None, enumerators=None, **kwargs):
        # The TesterPresentSender can interfere with a enumerator, since a
        # target may only allow one request at a time.
        # The SingleConversationSocket prevents interleaving requests.
        if not isinstance(socket, SingleConversationSocket):
            self.socket = SingleConversationSocket(socket)
        else:
            self.socket = socket
        self.tps = None  # TesterPresentSender
        self.target_state = ECU_State()
        self.reset_handler = reset_handler
        self.verbose = kwargs.get("verbose", False)
        if enumerators:
            # enumerators can be a mix of classes or instances
            self.enumerators = [
                e(self.socket)
                for e in enumerators if not isinstance(e, Enumerator)
            ] + [e for e in enumerators if isinstance(e, Enumerator)
                 ]  # noqa: E501
        else:
            self.enumerators = [
                e(self.socket) for e in self.default_enumerator_clss
            ]  # noqa: E501
        self.enumerator_classes = [e.__class__ for e in self.enumerators]
        self.state_graph = Graph()
        self.state_graph.add_edge(ECU_State(), ECU_State())
        self.configuration = \
            {"dynamic_timeout": kwargs.pop("dynamic_timeout", False),
             "enumerator_classes": self.enumerator_classes,
             "verbose": self.verbose,
             "state_graph": self.state_graph,
             "delay_state_change": kwargs.pop("delay_state_change", 0.5)}

        for e in self.enumerators:
            self.configuration[e.__class__] = kwargs.pop(
                e.__class__.__name__ + "_kwargs", dict())

        for conf_key in self.enumerators:
            conf_val = self.configuration[conf_key.__class__]
            for kwargs_key, kwargs_val in kwargs.items():
                if kwargs_key not in conf_val.keys():
                    conf_val[kwargs_key] = kwargs_val
            self.configuration[conf_key.__class__] = conf_val

        log_interactive.debug("The following configuration was created")
        log_interactive.debug(self.configuration)
Esempio n. 18
0
    def _evaluate_response(
        self,
        state,  # type: EcuState
        request,  # type: Packet
        response,  # type: Optional[Packet]
        **kwargs  # type: Optional[Dict[str, Any]]
    ):  # type: (...) -> bool
        """
        Evaluates the response and determines if the current scan execution
        should be stopped.
        :param state: Current state of the ECU under test
        :param request: Sent request
        :param response: Received response
        :param kwargs: Arguments to modify the behavior of this function.
                       Supported arguments:
                         - retry_if_none_received: True/False
                         - exit_if_no_answer_received: True/False
                         - exit_if_service_not_supported: True/False
                         - exit_scan_on_first_negative_response: True/False
                         - retry_if_busy_returncode: True/False
        :return: True, if current execution needs to be interrupted.
                 False, if enumerator should proceed with the execution.
        """
        if response is None:
            if cast(bool, kwargs.pop("retry_if_none_received", False)):
                log_interactive.debug("[i] Retry %s because None received",
                                      repr(request))
                return self._populate_retry(state, request)
            return cast(bool, kwargs.pop("exit_if_no_answer_received", False))

        if self._evaluate_negative_response_code(state, response, **kwargs):
            # leave current execution, because of a negative response code
            return True

        if self._evaluate_retry(state, request, response, **kwargs):
            # leave current execution, because a retry was set
            return True

        # cleanup retry packet
        self._retry_pkt[state] = None

        return self._evaluate_ecu_state_modifications(state, request, response)
Esempio n. 19
0
    def _evaluate_retry(
        self,
        state,  # type: EcuState
        request,  # type: Packet
        response,  # type: Packet
        **kwargs  # type: Optional[Dict[str, Any]]
    ):  # type: (...) -> bool

        if super(GMLAN_SAEnumerator,
                 self)._evaluate_retry(state, request, response, **kwargs):
            return True

        if response.service == 0x7f and \
                self._get_negative_response_code(response) in [0x22, 0x37]:
            log_interactive.debug(
                "[i] Retry %s because requiredTimeDelayNotExpired or "
                "requestSequenceError received", repr(request))
            return super(GMLAN_SAEnumerator,
                         self)._populate_retry(state, request)
        return False
Esempio n. 20
0
 def scan(self):
     scan_complete = False
     while not scan_complete:
         scan_complete = True
         log_interactive.info("[i] Scan paths %s", self.get_state_paths())
         for p in self.get_state_paths():
             log_interactive.info("[i] Scan path %s", p)
             final_state = p[-1]
             for e in self.enumerators:
                 if e.state_completed[final_state]:
                     log_interactive.debug("[+] State %s for %s completed",
                                           repr(final_state), e)
                     continue
                 if not self.enter_state_path(p):
                     log_interactive.error("[-] Error entering path %s", p)
                     continue
                 log_interactive.info("[i] EXECUTE SCAN %s for path %s",
                                      e.__class__.__name__, p)
                 self.execute_enumerator(e)
                 scan_complete = False
     self.reset_target()
Esempio n. 21
0
    def __init__(self, test_cases, **kwargs):
        # type: (Union[List[Union[AutomotiveTestCaseABC, Type[AutomotiveTestCaseABC]]], List[Type[AutomotiveTestCaseABC]]], Any) -> None  # noqa: E501
        self.verbose = kwargs.get("verbose", False)
        self.debug = kwargs.get("debug", False)
        self.delay_state_change = kwargs.get("delay_state_change", 0.5)
        self.state_graph = Graph()

        # test_case can be a mix of classes or instances
        self.test_cases = \
            [e() for e in test_cases if not isinstance(e, AutomotiveTestCaseABC)]  # type: List[AutomotiveTestCaseABC]  # noqa: E501
        self.test_cases += \
            [e for e in test_cases if isinstance(e, AutomotiveTestCaseABC)]

        self.stages = [
            e for e in self.test_cases
            if isinstance(e, StagedAutomotiveTestCase)
        ]

        self.staged_test_cases = \
            [i for sublist in [e.test_cases for e in self.stages]
             for i in sublist]

        self.test_case_clss = set([
            case.__class__
            for case in set(self.staged_test_cases + self.test_cases)
        ])

        for cls in self.test_case_clss:
            kwargs_name = cls.__name__ + "_kwargs"
            self.__setattr__(cls.__name__, kwargs.pop(kwargs_name, dict()))

        for cls in self.test_case_clss:
            val = self.__getattribute__(cls.__name__)
            for kwargs_key, kwargs_val in kwargs.items():
                if kwargs_key not in val.keys():
                    val[kwargs_key] = kwargs_val
            self.__setattr__(cls.__name__, val)

        log_interactive.debug("The following configuration was created")
        log_interactive.debug(self.__dict__)
Esempio n. 22
0
    def scan(self, timeout=None):
        # type: (Optional[int]) -> None
        """
        Executes all testcases for a given time.
        :param timeout: Time for execution.
        :return: None
        """
        kill_time = time.time() + (timeout or 0xffffffff)
        while kill_time > time.time():
            test_case_executed = False
            log_interactive.debug("[i] Scan paths %s", self.state_paths)
            for p, test_case in product(self.state_paths,
                                        self.configuration.test_cases):
                log_interactive.info("[i] Scan path %s", p)
                terminate = kill_time < time.time()
                if terminate:
                    log_interactive.debug(
                        "[-] Execution time exceeded. Terminating scan!")
                    break

                final_state = p[-1]
                if test_case.has_completed(final_state):
                    log_interactive.debug("[+] State %s for %s completed",
                                          repr(final_state), test_case)
                    continue

                try:
                    if not self.enter_state_path(p):
                        log_interactive.error("[-] Error entering path %s", p)
                        continue
                    log_interactive.info("[i] Execute %s for path %s",
                                         str(test_case), p)
                    self.execute_test_case(test_case)
                    test_case_executed = True
                except (OSError, ValueError, Scapy_Exception) as e:
                    log_interactive.critical("[-] Exception: %s", e)
                    if self.configuration.debug:
                        raise e
                    if isinstance(e, OSError):
                        log_interactive.critical(
                            "[-] OSError occurred, closing socket")
                        self.socket.close()
                    if cast(SuperSocket, self.socket).closed and \
                            self.reconnect_handler is None:
                        log_interactive.critical(
                            "Socket went down. Need to leave scan")
                        raise e
                finally:
                    self.cleanup_state()

            if not test_case_executed:
                log_interactive.info(
                    "[i] Execute failure or scan completed. Exit scan!")
                break

        self.cleanup_state()
        self.reset_target()
Esempio n. 23
0
    def _populate_retry(
            self,
            state,  # type: EcuState
            request,  # type: Packet
    ):  # type: (...) -> bool
        """
        Populates internal storage with request for a retry.

        :param state: Current state
        :param request: Request which needs a retry
        :return: True, if storage was populated. If False is returned, the
                 retry storage is still populated. This indicates that the
                 current execution was already a retry execution.
        """

        if self._retry_pkt[state] is None:
            # This was no retry since the retry_pkt is None
            self._retry_pkt[state] = request
            log_interactive.debug("[-] Exit execute. Retry packet next time!")
            return True
        else:
            # This was a unsuccessful retry, continue execute
            log_interactive.debug("[-] Unsuccessful retry!")
            return False
Esempio n. 24
0
 def evaluate_security_access_response(res, seed, key):
     # type: (Optional[Packet], Packet, Optional[Packet]) -> bool
     if res is None or res.service == 0x7f:
         log_interactive.debug(repr(seed))
         log_interactive.debug(repr(key))
         log_interactive.debug(repr(res))
         log_interactive.info("Security access error!")
         return False
     else:
         log_interactive.info("Security access granted!")
         return True
Esempio n. 25
0
    def execute_test_case(self, test_case):
        # type: (AutomotiveTestCaseABC) -> None
        """
        This function ensures the correct execution of a testcase, including
        the pre_execute, execute and post_execute.
        Finally the testcase is asked if a new edge or a new testcase was
        generated.
        :param test_case: A test case to be executed
        :return: None
        """
        test_case.pre_execute(self.socket, self.target_state,
                              self.configuration)

        try:
            test_case_kwargs = self.configuration[test_case.__class__.__name__]
        except KeyError:
            test_case_kwargs = dict()

        log_interactive.debug("[i] Execute test_case %s with args %s",
                              test_case.__class__.__name__, test_case_kwargs)

        test_case.execute(self.socket, self.target_state, **test_case_kwargs)
        test_case.post_execute(self.socket, self.target_state,
                               self.configuration)

        if isinstance(test_case, StateGenerator):
            edge = test_case.get_new_edge(self.socket, self.configuration)
            if edge:
                log_interactive.debug("Edge found %s", edge)
                tf = test_case.get_transition_function(self.socket, edge)
                self.state_graph.add_edge(edge, tf)

        if isinstance(test_case, TestCaseGenerator):
            new_test_case = test_case.get_generated_test_case()
            if new_test_case:
                log_interactive.debug("Testcase generated %s", new_test_case)
                self.configuration.add_test_case(new_test_case)
Esempio n. 26
0
 def debug(self, lvl, msg):
     if self.debug_level >= lvl:
         log_interactive.debug(msg)
Esempio n. 27
0
 def debug(self, lvl, msg):
     if self.debug_level >= lvl:
         log_interactive.debug(msg)
Esempio n. 28
0
    def execute(self, socket, state, **kwargs):
        # type: (_SocketUnion, EcuState, Any) -> None
        self.check_kwargs(kwargs)
        timeout = kwargs.pop('timeout', 1)
        execution_time = kwargs.pop("execution_time", 1200)

        state_block_list = kwargs.get('state_block_list', list())

        if state_block_list and state in state_block_list:
            self._state_completed[state] = True
            log_interactive.debug("[i] State %s in block list!", repr(state))
            return

        state_allow_list = kwargs.get('state_allow_list', list())

        if state_allow_list and state not in state_allow_list:
            self._state_completed[state] = True
            log_interactive.debug("[i] State %s not in allow list!",
                                  repr(state))
            return

        it = self.__get_request_iterator(state, **kwargs)

        # log_interactive.debug("[i] Using iterator %s in state %s", it, state)

        start_time = time.time()
        log_interactive.debug("[i] Start execution of enumerator: %s",
                              time.ctime(start_time))

        for req in it:
            try:
                res = socket.sr1(req, timeout=timeout, verbose=False)
            except (OSError, ValueError, Scapy_Exception) as e:
                if not self._populate_retry(state, req):
                    log_interactive.critical(
                        "[-] Exception during retry. This is bad")
                raise e

            if socket.closed:
                if not self._populate_retry(state, req):
                    log_interactive.critical(
                        "[-] Socket closed during retry. This is bad")
                log_interactive.critical("[-] Socket closed during scan.")
                raise Scapy_Exception("Socket closed during scan")

            self._store_result(state, req, res)

            if self._evaluate_response(state, req, res, **kwargs):
                log_interactive.debug("[i] Stop test_case execution because "
                                      "of response evaluation")
                return

            if (start_time + execution_time) < time.time():
                log_interactive.debug(
                    "[i] Finished execution time of enumerator: %s",
                    time.ctime())
                return

        log_interactive.info("[i] Finished iterator execution")
        self._state_completed[state] = True
        log_interactive.debug("[i] States completed %s",
                              repr(self._state_completed))
Esempio n. 29
0
    def execute(self, socket, state, **kwargs):
        # type: (_SocketUnion, EcuState, Any) -> None
        self.check_kwargs(kwargs)
        timeout = kwargs.pop('timeout', 1)
        execution_time = kwargs.pop("execution_time", 1200)

        state_block_list = kwargs.get('state_block_list', list())

        if state_block_list and state in state_block_list:
            self._state_completed[state] = True
            log_interactive.debug("[i] State %s in block list!", repr(state))
            return

        state_allow_list = kwargs.get('state_allow_list', list())

        if state_allow_list and state not in state_allow_list:
            self._state_completed[state] = True
            log_interactive.debug("[i] State %s not in allow list!",
                                  repr(state))
            return

        it = self.__get_request_iterator(state, **kwargs)

        # log_interactive.debug("[i] Using iterator %s in state %s", it, state)

        start_time = time.time()
        log_interactive.debug("[i] Start execution of enumerator: %s",
                              time.ctime(start_time))

        for req in it:
            res = self.sr1_with_retry_on_error(req, socket, state, timeout)

            self._store_result(state, req, res)

            if self._evaluate_response(state, req, res, **kwargs):
                log_interactive.debug("[i] Stop test_case execution because "
                                      "of response evaluation")
                return

            if (start_time + execution_time) < time.time():
                log_interactive.debug(
                    "[i] Finished execution time of enumerator: %s",
                    time.ctime())
                return

        log_interactive.info("[i] Finished iterator execution")
        self._state_completed[state] = True
        log_interactive.debug("[i] States completed %s",
                              repr(self._state_completed))