def _validate_domain(self, param):

        if len(param) > 255:
            return False
        if phantom.is_ip(param):
            return False
        if param[-1] == '.':
            param = param[:-1]
        allowed = re.compile(r"(?!-)[A-Z\\d\-_]{1,63}(?<!-')$", re.IGNORECASE)
        parts = param.split('.')

        # Wildcard search '*' is allowed in the first and
        # last subdomain only
        for idx, x in enumerate(parts):
            if idx == 0 or idx == (len(parts) - 1):
                if not (x == '*' or allowed.match(x)):
                    return False
            elif not allowed.match(x):
                return False
        return True
Beispiel #2
0
    def _modify_device(self,
                       action_result,
                       ip_hostname,
                       action="cmd_isolate_agent"):
        endpoint = APEX_ONE_PRODUCT_AGENTS_ENDPOINT

        payload = {"act": action, "allow_multiple_match": False}

        if phantom.is_ip(ip_hostname):
            payload["ip_address"] = ip_hostname
        else:
            payload["host_name"] = ip_hostname

        req_payload = json.dumps(payload)

        ret_val, response = self._make_rest_call(endpoint,
                                                 action_result,
                                                 "post",
                                                 data=req_payload)

        return ret_val, response
Beispiel #3
0
    def _test_connectivity(self, param):
        """
        Called when the user depresses the test connectivity button on the Phantom UI.
        Use a basic query to determine if the device IP/hostname, username and password is correct
        """

        action_result = ActionResult()
        self.save_progress(FORTIGATE_TEST_CONNECTIVITY_MSG)
        self.save_progress("Configured URL: {}".format(self._device))

        ret_val = self._login(action_result)

        if phantom.is_fail(ret_val):
            # self.save_progress("Test Connectivity Failed")
            self.save_progress(action_result.get_message())
            # return action_result.get_status()

            # If SSL is enabled and URL configuration has IP address
            if self._verify_server_cert and (phantom.is_ip(self._device)
                                             or self._is_ipv6(self._device)):
                # The failure could be due to IP provided in URL instead of hostname
                self.save_progress(FORTIGATE_TEST_WARN_MSG)

            self.set_status(phantom.APP_ERROR, FORTIGATE_TEST_CONN_FAIL)
            return action_result.get_status()

        self.save_progress(FORTIGATE_TEST_ENDPOINT_MSG)

        # Querying endpoint to check connection to device
        status, _ = self._make_rest_call(FORTIGATE_BLOCKED_IPS, action_result)

        if phantom.is_fail(status):
            self.save_progress(action_result.get_message())
            self.set_status(phantom.APP_ERROR, FORTIGATE_TEST_CONN_FAIL)
            return action_result.get_status()

        self.set_status_save_progress(phantom.APP_SUCCESS,
                                      FORTIGATE_TEST_CONN_SUCC)
        return action_result.get_status()
Beispiel #4
0
    def _is_ip(self, ip_addr):

        try:
            ip_addr = self._handle_py_ver_compat_for_input_str(
                self._python_version, ip_addr)
            ip, net_size, net_mask = self._break_ip_addr(ip_addr.strip())
        except Exception as e:
            error_code, error_msg = self._get_error_message_from_exception(e)
            self.debug_print(
                "Validation for ip_addr failed. Error Code:{0}. Error Message:{1}. For valid IP formats, please refer to the action's documentation."
                .format(error_code, error_msg))
            return False

        # Validate ip address
        if not phantom.is_ip(ip):
            return False

        # Regex to validate the subnet
        reg_exp = re.compile(
            '^((128|192|224|240|248|252|254).0.0.0)|(255.(((0|128|192|224|240|248|252|254).0.0)'
            '|(255.(((0|128|192|224|240|248|252|254).0)|255.(0|128|192|224|240|248|252|254|255)))))$'
        )

        # Validate subnet
        if net_mask:
            if not reg_exp.match(net_mask):
                return False

        if net_size:
            try:
                net_size = int(net_size)
            except:
                self.debug_print("net_size: {0} invalid int".format(net_size))
                return False

            if (not (0 < net_size <= 32)):
                return False

        return True
Beispiel #5
0
    def _handle_get_system_info(self, param):
        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))
        action_result = self.add_action_result(ActionResult(dict(param)))

        ip_hostname = param["ip_hostname"]

        endpoint = APEX_ONE_PRODUCT_AGENTS_ENDPOINT
        if phantom.is_ip(ip_hostname):
            qs = f"?ip_address={ip_hostname}"
        else:
            qs = f"?host_name={ip_hostname}"

        ret_val, response = self._make_rest_call("{0}{1}".format(endpoint, qs),
                                                 action_result,
                                                 params=None)

        if phantom.is_fail(ret_val):
            return action_result.get_status()

        if response and (not response.get("result_content")
                         or response.get("result_code") != 1):
            return action_result.set_status(phantom.APP_ERROR,
                                            APEX_ONE_RESPONSE_EMPTY_MSG)

        try:
            action_result.add_data(response["result_content"][0])

            summary = action_result.update_summary({})
            summary["msg"] = response.get("result_description", "")
            summary["total_objects"] = len(response["result_content"])
        except:
            return action_result.set_status(phantom.APP_ERROR,
                                            APEX_ONE_ERR_SERVER_RES)

        return action_result.set_status(phantom.APP_SUCCESS)
    def _lookup_rdata_ip(self, param):

        action_result = self.add_action_result(ActionResult(dict(param)))

        # Getting mandatory input parameter
        ip = param[DNSDB_JSON_IP]
        # Getting optional input parameter
        network_prefix = param.get(DNSDB_JSON_NETWORK_PREFIX)
        ret_val, network_prefix = self._validate_integer(action_result, network_prefix, DNSDB_NETWORK_PREFIX_KEY)
        if phantom.is_fail(ret_val):
            return action_result.get_status()
        limit = param.get(DNSDB_JSON_LIMIT, 200)
        ret_val, limit = self._validate_integer(action_result, limit, DNSDB_LIMIT_KEY)
        if phantom.is_fail(ret_val):
            return action_result.get_status()

        summary_data = action_result.update_summary({})

        if network_prefix is not None:
            # Validate network prefix
            # network prefix valid if between 0 and 32 for ipv4
            if phantom.is_ip(ip):
                net_prefix_valid = 0 <= network_prefix <= 32
            else:
                # network prefix valid if between 0 and 128 for ipv6
                net_prefix_valid = 0 <= network_prefix <= 128

            if not net_prefix_valid:
                self.debug_print(DNSDB_ERR_INVALID_NETWORK_PREFIX.format(prefix=network_prefix))
                return action_result.set_status(
                    phantom.APP_ERROR,
                    DNSDB_ERR_INVALID_NETWORK_PREFIX.format(prefix=network_prefix))

        # Endpoint as per parameter given
        if network_prefix is not None:
            ip = "%s,%s" % (ip, network_prefix)

        # Constructing request parameters based on input
        # Validating the input parameters provided
        # Would be used during REST call
        ret_val, timestamps = self._validate_params(param, action_result)

        # Something went wrong while validing input parameters
        if phantom.is_fail(ret_val):
            return action_result.get_status()

        try:
            responses = list(self._client.lookup_rdata_ip(ip,
                                                        limit=limit,
                                                        time_first_before=timestamps[0],
                                                        time_first_after=timestamps[1],
                                                        time_last_before=timestamps[2],
                                                        time_last_after=timestamps[3],
                                                        ignore_limited=True))
        except dnsdb2.exceptions.AccessDenied:
            return action_result.set_status(
                phantom.APP_ERROR, DNSDB_REST_RESP_ACCESS_DENIED_MSG)
        except dnsdb2.exceptions.QuotaExceeded:
            return action_result.set_status(
                phantom.APP_ERROR, DNSDB_REST_RESP_LIC_EXCEED_MSG)
        except Exception as e:
            err = self._get_error_message_from_exception(e)
            return action_result.set_status(phantom.APP_ERROR, err)

        # Something went wrong with the request
        if phantom.is_fail(ret_val):
            return action_result.get_status()

        # No data is considered as app success
        if len(responses) == 0:
            return action_result.set_status(phantom.APP_SUCCESS, DNSDB_DATA_NOT_AVAILABLE_MSG)

        # To display count of domains in summary data
        count_domain = set()

        for resp in responses:

            if 'rrname' in resp:
                resp['rrname'] = resp['rrname'].rstrip('.')
                count_domain.add(resp['rrname'])

            # Response from the API is list of rdata.
            # Adding Each data of list to action_result
            action_result.add_data(resp)

        summary_data['total_domains'] = len(count_domain)

        return action_result.set_status(phantom.APP_SUCCESS)
Beispiel #7
0
    def _lookup_ip(self, param):

        action_result = self.add_action_result(ActionResult(dict(param)))

        # Getting mandatory input parameter
        ip = param[DNSDB_JSON_IP]
        # Getting optional input parameter
        network_prefix = param.get(DNSDB_JSON_NETWORK_PREFIX)

        summary_data = action_result.update_summary({})

        if network_prefix:
            # Validate network prefix
            # network prefix valid if between 0 and 32 for ipv4
            if phantom.is_ip(ip):
                net_prefix_valid = 0 <= int(network_prefix) <= 32
            else:
                # network prefix valid if between 0 and 128 for ipv6
                net_prefix_valid = 0 <= int(network_prefix) <= 128

            if not net_prefix_valid:
                self.debug_print(
                    DNSDB_ERR_INVALID_NETWORK_PREFIX.format(
                        prefix=network_prefix))
                return action_result.set_status(
                    phantom.APP_ERROR,
                    DNSDB_ERR_INVALID_NETWORK_PREFIX.format(
                        prefix=network_prefix))

        # Endpoint as per parameter given
        if network_prefix:
            endpoint = (DNSDB_ENDPOINT_IP_PREFIX).format(ip=ip,
                                                         prefix=network_prefix)
        else:
            endpoint = (DNSDB_ENDPOINT_IP).format(ip=ip)

        # Constructing request parameters based on input
        # Validating the input parameters provided
        # Would be used during REST call
        ret_val, url_params = self._get_url_params(param, action_result)

        # Something went wrong while validing input parameters
        if phantom.is_fail(ret_val):
            return action_result.get_status()

        ret_val, response = self._make_rest_call(endpoint,
                                                 action_result,
                                                 params=url_params)

        # Something went wrong with the request
        if phantom.is_fail(ret_val):
            return action_result.get_status()

        # No data is considered as app success
        if (response.get(DNSDB_REST_RESP_RESOURCE_NOT_FOUND_MSG)):
            return action_result.set_status(phantom.APP_SUCCESS,
                                            DNSDB_DATA_NOT_AVAILABLE_MSG)

        json_resp = response.get(DNSDB_JSON_RESPONSE)
        # To display count of domains in summary data
        count_domain = set()

        for resp in json_resp:

            if ('rrname' in resp):
                resp['rrname'] = resp['rrname'].rstrip('.')
                count_domain.add(resp['rrname'])

            # Response from the API is list of rdata.
            # Adding Each data of list to action_result
            action_result.add_data(resp)

        summary_data['total_domains'] = len(count_domain)

        return action_result.set_status(phantom.APP_SUCCESS)