def _url_void_function(self, event, *args, **kwargs):
        """Function: Retrieves information of a URL from the  URL Void database."""
        try:
            yield StatusMessage("URL Void function started...")
            rp = ResultPayload("fn_url_void", **kwargs)

            # Add support for Requests Common
            req_common = RequestsCommon(self.opts, self.options)

            api_key = self.options.get("api_key")
            identifier = self.options.get("identifier", "api1000")

            # Get the function parameters:
            artifact_value = kwargs.get("artifact_value")  # text
            url_void_endpoint = self.get_select_param(kwargs.get("url_void_endpoint", "Retrieve"))  # select
            validate_fields(["artifact_value", "url_void_endpoint"], kwargs)

            log.info("artifact_value: %s", artifact_value)
            log.info("url_void_endpoint: %s", url_void_endpoint)

            response = call_url_void_api(req_common, artifact_value, identifier, api_key, url_void_endpoint)

            yield StatusMessage("URL Void function completed successfully...")
            results = rp.done(True, response)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            yield FunctionError(e)
Esempio n. 2
0
    def _panorama_get_address_groups_function(self, event, *args, **kwargs):
        """Function: Panorama get address groups returns the list of address groups """
        try:
            yield StatusMessage("Getting list of Address Groups")
            rp = ResultPayload("fn_pa_panorama", **kwargs)

            validate_fields(["panorama_name_parameter"], kwargs)

            # Get the function parameters:
            location = self.get_select_param(
                kwargs.get("panorama_location"))  # select
            vsys = kwargs.get("panorama_vsys")  # text
            name = kwargs.get(
                "panorama_name_parameter")  # text (optional parameter)

            # Log inputs
            if location is None:
                raise ValueError("panorama_location needs to be set.")
            log.info("panorama_location: {}".format(location))
            log.info("panorama_vsys: {}".format(vsys))
            log.info("panorama_name_parameter: {}".format(name))

            panorama_util = PanoramaClient(self.opts, location, vsys)
            response = panorama_util.get_address_groups(name)

            yield StatusMessage("{} groups returned.".format(
                response["result"]["@count"]))
            results = rp.done(True, response)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            yield FunctionError(e)
    def _panorama_edit_address_group_function(self, event, *args, **kwargs):
        """Function: Panorama edit address group edits an address group,
        ie: add or remove ip addresses from the group"""
        try:
            yield StatusMessage("Editing address group...")
            rp = ResultPayload("fn_pa_panorama", **kwargs)

            validate_fields(["panorama_name_parameter", "panorama_request_body"], kwargs)

            # Get the function parameters:
            location = self.get_select_param(kwargs.get("panorama_location"))  # select
            vsys = kwargs.get("panorama_vsys")  # text
            name = kwargs.get("panorama_name_parameter")  # text
            body = self.get_textarea_param(kwargs.get("panorama_request_body"))  # textarea

            # Log inputs
            if location is None:
                raise ValueError("panorama_location needs to be set.")
            log.info("panorama_location: {}".format(location))
            log.info("panorama_vsys: {}".format(vsys))
            log.info("panorama_name_parameter: {}".format(name))
            log.info("panorama_request_body: {}".format(body))

            panorama_util = PanoramaClient(self.opts, location, vsys)
            response = panorama_util.edit_address_groups(name, body)

            yield StatusMessage("Address Group Updated")
            results = rp.done(True, response)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            yield FunctionError(e)
Esempio n. 4
0
def selftest_function(opts):
    """
    Placeholder for selftest function. An example use would be to test package api connectivity.
    Suggested return values are be unimplemented, success, or failure.
    """
    try:
        options = opts.get("hibp", {})
        hibp_api_key = options.get("hibp_api_key")
        validate_fields(["[hibp_api_key]"], options)
        HAVE_I_BEEN_PWNED_API_KEY_URL: "https://haveibeenpwned.com/api/v3/"

        api_key_url = "{0}/{1}".format(HAVE_I_BEEN_PWNED_API_KEY_URL,
                                       hibp_api_key)
        breaches_response = requests.get(api_key_url)

        if breaches_response.status_code != 401:
            yield StatusMessage("Have I Been Pwned API Key has been found")
        else:
            yield StatusMessage(
                "Have I Been Pwned API Key has not been found. Please add API Key to app.config"
            )

        return {"state": "success"}
    except Exception:
        return {"state": "failed"}
Esempio n. 5
0
def selftest_function(opts):
    """test if host exists, if using TLS sends an empty email"""

    try:
        smtp_config_section = opts.get(CONFIG_DATA_SECTION, {})
        smtp_server = smtp_config_section.get("smtp_server")
        smtp_port = str(smtp_config_section.get("smtp_port",
                                                SMTP_DEFAULT_PORT))
        smtp_cafile = smtp_config_section.get("smtp_ssl_cafile", False)
        smtp_user = smtp_config_section.get("smtp_user")
        smtp_password = smtp_config_section.get("smtp_password")
        from_email_address = smtp_config_section.get("from_email_address",
                                                     smtp_user)
        smtp_ssl_mode = smtp_config_section.get("smtp_ssl_mode")

        smtp_conn_timeout = int(
            smtp_config_section.get("smtp_conn_timeout",
                                    SMTP_DEFAULT_CONN_TIMEOUT))

        validate_fields(["smtp_server", "smtp_port"], smtp_config_section)
        LOG.info("Validating connection to mail server")

        if smtp_ssl_mode == "ssl":
            LOG.info("Building SSL connection object")
            smtp_connection = smtplib.SMTP_SSL(
                host=smtp_server,
                port=smtp_port,
                certfile=smtp_cafile,
                context=SendSMTPEmail.get_smtp_ssl_context,
                timeout=smtp_conn_timeout)
        else:
            LOG.info("Building generic connection object")
            smtp_connection = smtplib.SMTP(host=smtp_server,
                                           port=smtp_port,
                                           timeout=smtp_conn_timeout)
            if smtp_ssl_mode == "starttls" and smtp_user:
                LOG.info("Starting TLS...")
                smtp_connection.ehlo()
                smtp_connection.starttls()
                smtp_connection.ehlo()
                LOG.info("Logging in to SMTP...")
                if not smtp_password:
                    raise Exception(
                        'An SMTP user has been set; the SMTP password from app.config cannot be null'
                    )

                smtp_connection.login(user=smtp_user, password=smtp_password)
                if from_email_address:
                    smtp_connection.sendmail(from_email_address,
                                             from_email_address,
                                             'this is a test email')

        return {"state": "success"}
    except Exception as err:
        LOG.error(err)
        return {"state": "failure"}
    finally:
        if smtp_connection:
            smtp_connection.quit()
    def _panorama_edit_users_in_a_group_function(self, event, *args, **kwargs):
        """Function: Panorama get address groups returns the list of address groups """
        try:
            # Response code should equal 20 indicating the call went through successfully
            PASS_CONSTANT = "20"

            yield StatusMessage("Editing list of users in a group")
            rp = ResultPayload("fn_pa_panorama", **kwargs)

            validate_fields(
                ["panorama_user_group_xpath", "panorama_user_group_xml"],
                kwargs)

            # Get the function parameters:
            user_group_xpath = kwargs.get("panorama_user_group_xpath")  # text
            user_group_xml = self.get_textarea_param(
                kwargs.get("panorama_user_group_xml"))  # textarea
            location = self.get_select_param(
                kwargs.get("panorama_location"))  # select

            # Log inputs
            log.info(u"panorama_user_group_xpath: {}".format(user_group_xpath))
            log.info(u"panorama_user_group_xml: {}".format(user_group_xml))

            panorama_util = PanoramaClient(self.opts, location, None)
            xml_response = panorama_util.edit_users_in_a_group(
                user_group_xpath, user_group_xml)
            dict_response = xmltodict.parse(xml_response)

            try:
                if dict_response["response"].get("@code") == PASS_CONSTANT:
                    yield StatusMessage("User group was successfully edited.")
                else:
                    raise FunctionError(
                        "Editing the user group was unsuccessful with code {}, raising FunctionError."
                        .format(dict_response["response"]["@code"]))
            except KeyError as e:
                yield StatusMessage("Editing the user group was unsuccessful.")
                raise FunctionError(e)

            # add to dict_response to allow for more options in Resilient scripting and make some actions easier
            dict_response["xml_response"] = xml_response
            results = rp.done(True, dict_response)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            yield FunctionError(e)
    def __init__(self, opts, location, vsys=None):
        pan_config = opts.get("fn_pa_panorama")
        pan_config["location"] = location

        # validate config fields
        validate_fields(["panorama_host", "api_key", "location"], pan_config)

        self.__key = pan_config["api_key"]
        self.__location = pan_config["location"]
        self.__vsys = vsys
        self.__output_format = "json"

        self.verify = str_to_bool(pan_config.get("cert", "True"))
        self.host = pan_config["panorama_host"]
        self.rc = RequestsCommon(opts, pan_config)
        self.query_parameters = self.__build_query_parameters()
    def _panorama_get_users_in_a_group_function(self, event, *args, **kwargs):
        """Function: Panorama get address groups returns the list of address groups """
        try:
            yield StatusMessage("Getting list of users in a group")
            rp = ResultPayload("fn_pa_panorama", **kwargs)

            validate_fields(["panorama_user_group_xpath"], kwargs)

            # Get the function parameters:
            user_group_xpath = kwargs.get("panorama_user_group_xpath")  # text
            location = self.get_select_param(
                kwargs.get("panorama_location"))  # select

            # Log inputs
            log.info("panorama_user_group_xpath: {}".format(user_group_xpath))

            panorama_util = PanoramaClient(self.opts, location, None)
            xml_response = panorama_util.get_users_in_a_group(user_group_xpath)
            dict_response = xmltodict.parse(xml_response)

            user_list = []
            try:
                members = dict_response["response"]["result"]["entry"]["user"][
                    "member"]
                if isinstance(members, list):
                    # Multiple existing users
                    for m in members:
                        user_list.append(m)
                else:
                    # Single user in group
                    user_list.append(members.get("#text"))
            except KeyError:
                # No users returned
                yield StatusMessage("No users returned.")

            yield StatusMessage("{} users returned.".format(len(user_list)))

            # add to dict_response to allow for more options in Resilient scripting and make some actions easier
            dict_response["user_list"] = user_list
            dict_response["xml_response"] = xml_response
            results = rp.done(True, dict_response)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            yield FunctionError(e)
def selftest_function(opts):
    try:
        options = opts.get("fn_res_to_icd", {})
        icd_email = options.get("icd_email")
        icd_pass = options.get("icd_pass")
        icd_url = options.get('icd_url')
        test_endpoint = '/oslc/ping/'
        log.info(icd_email)
        params = {"_lid": icd_email, "_lpwd": icd_pass}
        validate_fields(['icd_email', 'icd_pass', 'icd_url'], options)
        log.info('executing api call with credentials')
        response = requests.post(icd_url + test_endpoint,
                                 params=params,
                                 verify=False)
        log.info(response.status_code)
        return {"state": "success"}
    except Exception as err:
        log.error(err)
        return {"state": "failure"}
    def test_validate_fields(self):
        # validate_fields(fieldList, kwargs)
        test_dict = {"a": "a", "b": "b", "c": ''}

        validate_fields(("a", "b"), test_dict)

        with self.assertRaises(ValueError):
            validate_fields(("c"), test_dict)
            validate_fields(("d"), test_dict)
    def __init__(self, opts):
        """constructor provides access to the configuration options"""
        super(FunctionComponent, self).__init__(opts)
        self.options = opts.get("fn_url_void", {})

        validate_fields(["api_key"], self.options)
Esempio n. 12
0
    def test_validate_fields(self):
        # validate_fields(fieldList, kwargs)

        inputs = {
            "bool_input_true": True,
            "bool_input_false": False,
            "unicode_input": u" դ ե զ է ը թ ժ ի լ խ ծ կ հ ձ ղ ճ մ յ ն ",
            "str_input": "some text",
            "num_input": 123,
            "select_input": {"id": 111, "name": "select choice"},
            "multi_select_input": [{"id": 111, "name": "select choice one"}, {"id": 111, "name": "select choice two"}],
            "text_with_value_string": {"content": "mock text", "format": "text"},
            "empty_input": ''
        }

        mandatory_fields = [
            {"name": "str_input", "placeholder": "some text"}
        ]

        expected_output = {
            "bool_input_true": True,
            "bool_input_false": False,
            "unicode_input": u" դ ե զ է ը թ ժ ի լ խ ծ կ հ ձ ղ ճ մ յ ն ",
            "str_input": "some text",
            "num_input": 123,
            "select_input": "select choice",
            "multi_select_input": ["select choice one", "select choice two"],
            "text_with_value_string": "mock text",
            "empty_input": ''
        }

        # Test its runs as expected
        validate_fields(("bool_input_true", "unicode_input"), inputs)

        with self.assertRaisesRegex(ValueError, "'field_list' must be of type list/tuple"):
            validate_fields({}, inputs)

        # Test mandatory fields missing
        with self.assertRaisesRegex(ValueError,
                                    "'cx' is mandatory and is not set. You must set this value to run this function"):
            validate_fields(("cx"), inputs)

        # Test mandatory field is empty string
        with self.assertRaisesRegex(ValueError,
                                    "'empty_input' is mandatory and is not set. You must set this value to run this function"):
            validate_fields(("empty_input"), inputs)

        # Test no mandatory fields
        self.assertEquals(validate_fields([], inputs), expected_output)

        # Test getting single input from returned dict
        self.assertEquals(validate_fields(("bool_input_true"), inputs).get("bool_input_true"), True)
        self.assertEquals(validate_fields([], inputs).get("bool_input_true"), True)

        # Test getting value defined as False
        self.assertEquals(validate_fields(["bool_input_false"], inputs).get("bool_input_false"), False)

        # Test select + multi-select type fields
        self.assertEquals(validate_fields(["select_input"], inputs).get("select_input"), "select choice")
        self.assertEquals(validate_fields([], inputs).get("multi_select_input"),
                          ["select choice one", "select choice two"])

        # Test 'Text with value string Input' type
        self.assertEquals(validate_fields(["text_with_value_string"], inputs).get("text_with_value_string"),
                          "mock text")

        # Test placeholder
        with self.assertRaisesRegex(ValueError,
                                    "'str_input' is mandatory and still has its placeholder value of 'some text'. You must set this value correctly to run this function"):
            validate_fields(mandatory_fields, inputs)

        # Test works with a namedtuple
        inputs_as_named_tuple = namedtuple("fn_inputs", inputs.keys())(*inputs.values())
        self.assertEquals(validate_fields(("bool_input_true"), inputs_as_named_tuple).get("bool_input_true"), True)

        validated_named_tuple_inputs_i = validate_fields([], inputs_as_named_tuple)
        self.assertEquals(validated_named_tuple_inputs_i, expected_output)

        # Test called again on a normalized dict
        validated_named_tuple_inputs_ii = validate_fields([], validated_named_tuple_inputs_i)
        self.assertEquals(validated_named_tuple_inputs_ii, expected_output)
Esempio n. 13
0
 def _res_to_icd_function_function(self, event, *args, **kwargs):
     try:
         # taken from config section
         icd_email = self.options.get("icd_email")
         icd_pass = self.options.get("icd_pass")
         icd_priority = self.options.get("icd_priority")
         icd_field_severity = self.options.get('icd_field_severity')
         icd_url = self.options.get('icd_url')
         incident_id = kwargs.get("incident_id")
         # Payload and validation
         payload = ResultPayload('fn_res_to_icd', **kwargs)
         validate_fields(
             ['icd_email', 'icd_pass', 'icd_url', 'icd_field_severity'],
             self.options)
         validate_fields(['incident_id'], kwargs)
         #logging
         log = logging.getLogger(__name__)
         log.info("icd_email: %s", icd_email)
         log.info("icd_field_severity: %s", icd_field_severity)
         log.info("icd_priority: %s", icd_priority)
         log.info("incident_id: %s", incident_id)
         log.info("icd_url: %s", icd_url)
         # Resilient client and api calls
         res_client = self.rest_client()
         incident_str = '/incidents/{incident_id}/'.format(
             incident_id=incident_id)
         artifact_str = '/incidents/{incident_id}/artifacts'.format(
             incident_id=incident_id)
         field_severity = {}
         if icd_field_severity:
             # If api call for custom severity field is not successful, Ticket defaults to minimum priority
             try:
                 fieldsev_str = '/types/{type}/fields/{field}'.format(
                     type='incident', field=icd_field_severity)
                 field_severity = res_client.get(fieldsev_str)
             except:
                 field_severity['values'] = MIN_PRIORITY_ICD
         content = res_client.get(incident_str)
         art_content = res_client.get(artifact_str)
         # Time and date
         timestamp = content['create_date']
         timeval = readable_datetime(timestamp,
                                     milliseconds=True,
                                     rtn_format='%Y-%m-%dT%H:%M:%SZ')
         time = "Date and Time: {0}".format(timeval)
         #artifact population to icd ticket
         details_payload = ''
         i = 0
         j = 0
         if icd_field_severity:
             try:
                 for i in range(0, len(art_content)):
                     if art_content[i].get('properties', False):
                         if art_content[i]['properties'][0]['name'] in (
                                 'source', 'destination'):
                             j += 1
                             details_payload += 'ID: {1} IP Address {2}: {0} \n'.format(
                                 art_content[i]['value'],
                                 art_content[i]['id'], art_content[i]
                                 ['properties'][0]['name'].capitalize())
                             log.info("Artifacts added to ICD ticket: {0}".
                                      format(j))
             except Exception as artifact_error:
                 log.error(artifact_error)
                 log.error("Encountered an error parsing artifacts")
         ##If you custom field isn't specified, it defaults to min priority
         if icd_field_severity:
             try:
                 field_sev = field_severity['values']
             except:
                 field_sev = field_severity['name']
             if not field_sev:
                 field_sev = 1  # number
             log.info("field_severity: %s", field_sev)
             icd_priority_lookup = [0, 4, 4, 4, 3, 2, 2, 1]
             try:
                 icd_priority = icd_priority_lookup[field_sev]
                 log.info("icd_priority: %s", field_sev)
             except:
                 log.warning(
                     "You have not set a priority, icd priority will be set to min value (4)"
                 )
                 icd_priority = MIN_PRIORITY_ICD
         # Params and Desk call
         params = {
             "DESCRIPTION": time,
             "DESCRIPTION_LONGDESCRIPTION": details_payload,
             "REPORTEDBYID": icd_email,
             "logtype": "CLIENTNOTE",
             "worklog.1.description": "SECURITY ISSUE",
             "worklog.1.DESCRIPTION_LONGDESCRIPTION": "SECURITY ISSUE",
             "INTERNALPRIORITY": icd_priority,
             "SITEID": "APPOPINT",
             "CLASSIFICATIONID": "SECURITY ISSUE",
             "_lid": icd_email,
             "_lpwd": icd_pass
         }
         endpoint = "/rest/os/MXINCIDENT/"
         base_url = icd_url + endpoint
         response = requests.post(url=base_url, params=params, verify=False)
         xmldata = bsoup(response.text, "html.parser")
         icd_id = '{0}'.format(xmldata.createmxincidentresponse.
                               mxincidentset.incident.ticketid)
         icd_id = re.sub('[ticket<>/d]', '', icd_id)
         yield StatusMessage("Completed successfully")
         results = payload.done(success=True,
                                content={
                                    "incident_escalated": incident_id,
                                    "icd_id": icd_id,
                                    "details": details_payload
                                })
         # Produce a FunctionResult with the results
         yield FunctionResult(results)
         log.info("Complete")
     except Exception:
         yield FunctionError()