def send_mitigation_action_by_mac(self, mac_address, action):
        """
        Send an EPS mitigation action for an endpoint MAC address.

        :param str mac_address: MAC address of the endpoint for which the
            action should be performed.
        :param dxlciscopxgridclient.constants.EpsAction action: The action to
            perform.
        :return: Results of the attempt to send the action. The results for a
            successful send should look similar to this:

            .. code-block:: json

                {
                    "gid": "150",
                    "macInterface": "00:11:22:33:44:55",
                    "mitigationStatus": "complete"
                }
        :rtype: dict
        """
        request = Request(self._EPS_SEND_MITIGATION_ACTION_BY_MAC)
        MessageUtils.dict_to_json_payload(request, {
            _PARAM_MAC: mac_address,
            _PARAM_ACTION: action
        })
        return MessageUtils.json_payload_to_dict(
            self._pxgrid_client._dxl_sync_request(request))
    def retrieve_policy_by_name(self, policy_name):
        """
        Retrieve information for an ANC policy by name.

        :param str policy_name: Name of the policy.
        :return: The policy information, which should look similar to this:

            .. code-block:: json

                    {
                        "ancStatus": "success",
                        "ancpolicy": [
                            {
                                "action": [
                                    "Quarantine"
                                ],
                                "name": "quarantine_policy"
                            }
                        ]
                    }
        :rtype: dict
        :raises Exception: If the policy name has not been defined.
        """
        request = Request(self._ANC_RETRIEVE_POLICY_BY_NAME)
        MessageUtils.dict_to_json_payload(request,
                                          {_PARAM_POLICY_NAME: policy_name})
        return MessageUtils.json_payload_to_dict(
            self._pxgrid_client._dxl_sync_request(request))
    def test_callback_statsremained(self):
        with MockServerRunner() as server_runner:
            with UrlVoidApiService(TEST_FOLDER) as urlvoid_service:

                urlvoid_service.URL_VOID_API_URL_FORMAT = "http://127.0.0.1:" \
                                              + str(server_runner.mock_server_port) \
                                              + "/api1000/{0}/"

                urlvoid_service.run()

                request_topic = UrlVoidApiService.REQ_TOPIC_STATS_REMAINED
                req = Request(request_topic)
                MessageUtils.dict_to_json_payload(
                    req,
                    {
                        UrlVoidApiCallback.PARAM_HOST: SAMPLE_HOST
                    }
                )

                res = urlvoid_service._dxl_client.sync_request(req, timeout=30)

                self.assertEqual(
                    dicttoxml(
                        SAMPLE_REMAINED_OUTPUT,
                        custom_root=XML_ROOT_RESPONSE,
                        attr_type=False
                    ),
                    res.payload
                )
    def send_mitigation_action_by_ip(self, ip_address, action):
        """
        Send an EPS mitigation action for an endpoint IP address.

        :param str ip_address: IP address of the endpoint for which the action
            should be performed.
        :param dxlciscopxgridclient.constants.EpsAction action: The action to
            perform.
        :return: Results of the attempt to send the action. The results for a
            successful send should look similar to this:

            .. code-block:: json

                {
                    "gid": "150",
                    "macInterface": "00:11:22:33:44:55",
                    "mitigationStatus": "complete"
                }
        :rtype: dict
        :raises Exception: If no session has been established for an endpoint
            which corresponds to the IP address.
        """
        request = Request(self._EPS_SEND_MITIGATION_ACTION_BY_IP)
        MessageUtils.dict_to_json_payload(request, {
            _PARAM_IP: ip_address,
            _PARAM_ACTION: action,
            "foo": "bar"
        })
        return MessageUtils.json_payload_to_dict(
            self._pxgrid_client._dxl_sync_request(request))
    def on_request(self, request):
        """
        Callback invoked when a request is received.

        :param dxlclient.message.Request request: The request
        """
        logger.info("Request received on topic '%s'",
                    request.destination_topic)
        logger.debug("Payload for topic %s: %s", request.destination_topic,
                     request.payload)

        try:
            request_dict = MessageUtils.json_payload_to_dict(request) \
                if request.payload else {}
            if "event" in request_dict and \
                    type(request_dict["event"]).__name__ in ("str", "unicode") and \
                    request_dict["event"].isdigit():
                request_dict["event"] = int(request_dict["event"])

            response_data = self._api_method(**request_dict)
            if isinstance(response_data, dict) and \
                    response_data.get("errors", None):
                res = ErrorResponse(request,
                                    error_message=str(
                                        response_data["errors"][0]))
            else:
                res = Response(request)
            MessageUtils.dict_to_json_payload(res, response_data)
        except Exception as ex:
            error_str = str(ex)
            logger.exception("Error handling request: %s", error_str)
            res = ErrorResponse(request,
                                error_message=MessageUtils.encode(error_str))

        self._app.client.send_response(res)
    def _request(self, dxl_request, path, request_fn, body=None):
        """
        Make a request to TheHive server, delivering the response to the
        DXL fabric.

        :param dxlclient.message.Request dxl_request: DXL request containing
            parameters to forward along in a request to TheHive server.
        :param str path: URL subpath for the request to send to TheHive server.
        :param function request_fn: Callback which is invoked to make
            TheHive request.
        :param str body: Request body to include in the request.
        """
        try:
            request_url = self._api_url + path
            response = request_fn(request_url, body)
            if 200 <= response.status_code <= 299:
                # TheHive request was successful so forward the response
                # along as-is to the DXL fabric.
                res = Response(dxl_request)
                MessageUtils.dict_to_json_payload(res, response.json())
            else:
                # TheHive request encountered an error. Attempt to decode
                # an error message from the response body.
                res = self._build_http_error_response(dxl_request, response)
        except Exception as ex:
            error_str = str(ex)
            logger.exception("Error handling request: %s", error_str)
            res = ErrorResponse(dxl_request,
                                error_message=MessageUtils.encode(error_str))
        self._dxl_client.send_response(res)
    def _sync_request(dxl_client, request, response_timeout, payload_dict):
        """
        Performs a synchronous DXL request and returns the payload

        :param dxl_client: The DXL client with which to perform the request
        :param request: The DXL request to send
        :param response_timeout: The maximum amount of time to wait for a response
        :param payload_dict: The dictionary (``dict``) to use as the payload of the DXL request
        :return: The result of the remote command execution (resulting payload)
        """
        # Set the payload
        MessageUtils.dict_to_json_payload(request, payload_dict)

        # Display the request that is going to be sent
        logger.debug(
            "Request:\n%s",
            MessageUtils.dict_to_json(payload_dict, pretty_print=True))

        # Send the request and wait for a response (synchronous)
        res = dxl_client.sync_request(request, timeout=response_timeout)

        if res.message_type == Message.MESSAGE_TYPE_ERROR:
            raise Exception("Error: " + res.error_message + " (" +
                            str(res.error_code) + ")")

        # Return a dictionary corresponding to the response payload
        ret_val = MessageUtils.decode_payload(res)

        # Display the response
        logger.debug("Response:\n%s", ret_val)
        return ret_val
    def get_endpoint_by_mac(self, mac_address):
        """
        Get information for an endpoint by its MAC address.

        :param str mac_address: MAC address of the endpoint.
        :return: The endpoint information, which should look similar to this:

            .. code-block:: json

                {
                    "ancEndpoint": [
                        {
                            "macAddress": "00:11:22:33:44:55",
                            "policyName": "quarantine_policy"
                        }
                    ],
                    "ancStatus": "success"
                }
        :rtype: dict
        :raises Exception: If no policy has been associated with the endpoint.
        """
        request = Request(self._ANC_GET_ENDPOINT_BY_MAC)
        MessageUtils.dict_to_json_payload(request, {_PARAM_MAC: mac_address})
        return MessageUtils.json_payload_to_dict(
            self._pxgrid_client._dxl_sync_request(request))
    def apply_endpoint_policy_by_mac(self, mac_address, policy_name):
        """
        Apply a policy to an endpoint by its MAC address.

        :param str mac_address: MAC address of the endpoint.
        :param str policy_name: Name of the policy to apply.
        :return: Results of the attempt to apply the endpoint policy. On a
            successful application, the results should look similar to this:

            .. code-block:: json

                {
                    "ancStatus": "success"
                }
        :rtype: dict
        :raises Exception: If the supplied policy name has already been
            applied to the endpoint or the policy name has not been defined.
        """
        request = Request(self._ANC_APPLY_ENDPOINT_POLICY_BY_MAC)
        MessageUtils.dict_to_json_payload(request, {
            _PARAM_MAC: mac_address,
            _PARAM_POLICY_NAME: policy_name
        })
        return MessageUtils.json_payload_to_dict(
            self._pxgrid_client._dxl_sync_request(request))
示例#10
0
    def test_callback_parkeddomain(self):
        with BaseClientTest.create_client(max_retries=0) as dxl_client:
            dxl_client.connect()

            with MockServerRunner() as server_runner:
                with ApiVoidService(TEST_FOLDER) as apivoid_service:
                    apivoid_service._dxl_client = dxl_client

                    apivoid_service.API_VOID_URL_FORMAT = "http://127.0.0.1:" \
                                                  + str(server_runner.mock_server_port) \
                                                  + "/{0}/v1/pay-as-you-go/{1}"

                    apivoid_service.run()

                    request_topic = ApiVoidService.REQ_TOPIC_PARKED_DOMAIN
                    req = Request(request_topic)
                    MessageUtils.dict_to_json_payload(
                        req, {ApiVoidCallback.PARAM_HOST: SAMPLE_HOST})

                    res = apivoid_service._dxl_client.sync_request(req,
                                                                   timeout=30)

                    res_dict = MessageUtils.json_payload_to_dict(res)

                    self.assertDictEqual(SAMPLE_PARKED_DOMAIN, res_dict)
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param dxlclient.message.Request request: The request message
        """
        # Handle request
        logger.debug("Request received on topic: '%s'",
                     request.destination_topic)

        try:
            # Create response
            res = Response(request)

            # Store the next segment.
            result = self._store_manager.store_segment(request)

            # Set payload
            MessageUtils.dict_to_json_payload(res, result.to_dict())

            # Send response
            self._dxl_client.send_response(res)

        except Exception as ex:
            logger.exception("Error handling request")
            err_res = ErrorResponse(request, error_code=0,
                                    error_message=MessageUtils.encode(str(ex)))
            self._dxl_client.send_response(err_res)
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param request: The request message
        """
        # Handle request
        request_payload = MessageUtils.json_payload_to_dict(request)
        logger.info(
            "Request received on topic: '{0}' with payload: '{1}'".format(
                request.destination_topic, request_payload))
        if request.destination_topic in self._callbacks:
            try:
                self._callbacks[request.destination_topic](request,
                                                           request_payload)
            except Exception as ex:
                logger.exception("Error handling request")
                err_res = ErrorResponse(request, error_code=0,
                                        error_message=MessageUtils.encode(
                                            str(ex)))
                self._app.client.send_response(err_res)
        else:
            logger.exception("Unknown topic: %s", request.destination_topic)
            err_res = ErrorResponse(
                request,
                error_code=0,
                error_message=MessageUtils.encode(
                    "Unknown topic: " + request.destination_topic))
            self._app.client.send_response(err_res)
 def _pop_attribute_from_request(self, request, attr_name):
     """
     Pop the value for a named attribute from the supplied request JSON
     and return the remaining request body.
     :param request:
     :param attr_name:
     :return:
     :raises ValueError: if the named attribute does not appear in the
         request.
     :return: A tuple containing two elements: the value associated with
         the attr_name parameter and the request body (minus the attr_name
         attribute and its associated value), converted to a dict.
     :rtype: tuple
     """
     try:
         request_body = MessageUtils.json_payload_to_dict(request)
         attr_value = request_body.pop(attr_name, None)
         if not attr_name:
             raise ValueError("Attribute {} is missing".format(attr_name))
     except Exception as ex:
         request_body = {}
         attr_value = None
         error_str = str(ex)
         logger.exception("Error handling request: %s", error_str)
         res = ErrorResponse(request,
                             error_message=MessageUtils.encode(error_str))
         self._dxl_client.send_response(res)
     return (attr_value, request_body)
    def _invoke_service(self, request_method, request_dict):
        """
        Invokes a request method on the MISP DXL service.

        :param str request_method: The request method to append to the
            topic for the request.
        :param dict request_dict: Dictionary containing request information.
        :return: Results of the service invocation.
        :rtype: dict
        """
        if self._misp_service_unique_id:
            request_service_id = "/{}".format(self._misp_service_unique_id)
        else:
            request_service_id = ""

        # Create the DXL request message.
        request = Request("{}{}/{}".format(self._SERVICE_TYPE,
                                           request_service_id, request_method))

        # Set the payload on the request message (Python dictionary to JSON
        # payload).
        MessageUtils.dict_to_json_payload(request, request_dict)

        # Perform a synchronous DXL request.
        response = self._dxl_sync_request(request)

        # Convert the JSON payload in the DXL response message to a Python
        # dictionary and return it.
        return MessageUtils.json_payload_to_dict(response)
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param request: The request message
        """
        # Handle request
        request_payload = MessageUtils.json_payload_to_dict(request)
        if request.destination_topic in self._callbacks:
            try:
                self._callbacks[request.destination_topic](request,
                                                           request_payload)
            except Exception as ex:
                err_res = ErrorResponse(request,
                                        error_code=0,
                                        error_message=MessageUtils.encode(
                                            str(ex)))
                self._client.send_response(err_res)
        else:
            err_res = ErrorResponse(
                request,
                error_code=0,
                error_message=MessageUtils.encode("Unknown topic: " +
                                                  request.destination_topic))
            self._client.send_response(err_res)
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param request: The request message
        """
        request_payload = MessageUtils.json_payload_to_dict(request)

        try:
            res = Response(request)

            payload = {"code": 200, "body": {}}

            if request_payload["target"] == "/v1/simple":
                payload = self.v1_simple(request_payload, payload)
            else:
                payload = self.v1_complex(request_payload, payload)

            MessageUtils.dict_to_json_payload(res, payload)
            self._client.send_response(res)

        except Exception as ex:
            err_res = ErrorResponse(request,
                                    error_code=0,
                                    error_message=MessageUtils.encode(str(ex)))
            self._client.send_response(err_res)
示例#17
0
    def set_certificate_reputation(self, trust_level, sha1, public_key_sha1=None, comment=""):
        """
        Sets the "Enterprise" reputation (`trust level`) of a specified certificate (as identified by hashes).

        .. note::

            **Client Authorization**

            The OpenDXL Python client invoking this method must have permission to send messages to the
            ``/mcafee/service/tie/cert/reputation/set`` topic which is part of the
            ``TIE Server Set Enterprise Reputation`` authorization group.

            The following page provides an example of authorizing a Python client to send messages to an
            `authorization group`. While the example is based on McAfee Active Response (MAR), the
            instructions are the same with the exception of swapping the ``TIE Server Set Enterprise Reputation``
            `authorization group` in place of ``Active Response Server API``:

            `<https://opendxl.github.io/opendxl-client-python/pydoc/marsendauth.html>`_

        **Example Usage**

            .. code-block:: python

                    # Set the enterprise reputation (trust level) for the certificate to Known Trusted
                    tie_client.set_certificate_reputation(
                        TrustLevel.KNOWN_TRUSTED,
                        "1C26E2037C8E205B452CAB3565D696512207D66D",
                        public_key_sha1="B4C3B2D596D1461C1BB417B92DCD74817ABB829D",
                        comment="Reputation set via OpenDXL")

        :param trust_level: The new `trust level` for the file. The list of standard `trust levels` can be found in the
            :class:`dxltieclient.constants.TrustLevel` constants class.
        :param sha1: The SHA-1 of the certificate
        :param public_key_sha1: The SHA-1 of the certificate's public key (optional)
        :param comment: A comment to associate with the certificate (optional)
        """
        # Create the request message
        req = Request(TIE_SET_CERT_REPUTATION_TOPIC)

        # Create a dictionary for the payload
        payload_dict = {
            "trustLevel": trust_level,
            "providerId": CertProvider.ENTERPRISE,
            "comment": comment,
            "hashes": [
                {"type": "sha1", "value": self._hex_to_base64(sha1)}
            ]}

        # Add public key SHA-1 (if specified)
        if public_key_sha1:
            payload_dict["publicKeySha1"] = self._hex_to_base64(
                public_key_sha1)

        # Set the payload
        MessageUtils.dict_to_json_payload(req, payload_dict)

        # Send the request
        self._dxl_sync_request(req)
示例#18
0
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param request: The request message
        """
        # Handle request
        logger.info(
            "Request received on topic: '{0}' with payload: '{1}'".format(
                request.destination_topic,
                MessageUtils.decode_payload(request)))

        try:
            # Create response
            res = Response(request)

            # Read DXL request payload into dictionary
            params = MessageUtils.json_payload_to_dict(request)

            # Invoke API call
            if 'data' in params.keys() and params['data'] != "":
                tide_data = params['data']
                if 'type' in params.keys(): tide_type = params['type']
                else: tide_type = get_ioc_type(tide_data, 'tide')
                if 'rlimit' in params.keys(
                ) and params['max_rec'] < self._app.tide_max_rec:
                    tide_max_rec = params['max_rec']
                else:
                    tide_max_rec = self._app.tide_max_rec  #Error data is required

                if 'format' in params.keys(): tide_format = params['format']
                else:
                    tide_format = self._app.tide_format  #Error data is required
                http_res = requests.get(
                    "https://api.activetrust.net:8000/api/data/threats",
                    params={
                        "type": tide_type,
                        tide_type: tide_data,
                        "data_format": tide_format,
                        "rlimit": tide_max_rec
                    },
                    auth=(self._app.api_key, ''))
                content = unicode(http_res.content, "utf-8")
            else:
                content = "{'status':'error','errorMessage':'The data field is required'}"  #Error data is required

            # Add web service response to DXL response payload
            MessageUtils.encode_payload(res, content, enc='utf-8')

            # Send response
            self._app.client.send_response(res)

        except Exception as ex:
            logger.exception("Error handling request")
            err_res = ErrorResponse(request,
                                    error_code=0,
                                    error_message=MessageUtils.encode(str(ex)))
            self._app.client.send_response(err_res)
    def _set_item_reputation(self, request, request_payload,
                             change_topic, tags=None):
        new_entry = None

        hash_match_result = self._get_reputation_for_hashes(
            request_payload["hashes"], False)
        if hash_match_result:
            metadata = self.REPUTATION_METADATA[hash_match_result]
            new_reputations = metadata["reputations"]
            for reputation_entry in new_reputations:
                if reputation_entry["providerId"] == request_payload["providerId"]:
                    new_entry = reputation_entry
        else:
            first_hash = request_payload["hashes"][0]
            item_name = first_hash["type"] + ":" + first_hash["value"]
            new_reputations = []
            self.REPUTATION_METADATA[item_name] = {
                "hashes": {new_hash["type"]: new_hash["value"] \
                           for new_hash in request_payload["hashes"]},
                "reputations": new_reputations}
            metadata = self.REPUTATION_METADATA[item_name]
            self._set_hash_algos_for_item(item_name, metadata["hashes"])

        tags = tags or {}
        if "comment" in request_payload:
            tags["comment"] = request_payload["comment"]
        metadata["tags"] = tags

        old_reputations = copy.deepcopy(new_reputations)

        if not new_entry:
            new_entry = {"attributes": {},
                         "providerId": request_payload["providerId"]}
        new_entry["trustLevel"] = request_payload["trustLevel"]
        new_entry["createDate"] = int(time.time())
        new_reputations.append(new_entry)

        self._app.client.send_response(Response(request))

        event = Event(change_topic)
        event_payload = {
            "hashes": request_payload["hashes"],
            "oldReputations": {"reputations": old_reputations},
            "newReputations": {"reputations": new_reputations},
            "updateTime": int(time.time())
        }
        if "publicKeySha1" in metadata["hashes"]:
            event_payload["publicKeySha1"] = metadata["hashes"]["publicKeySha1"]
            event_payload["hashes"] = filter(
                lambda hash_entry: hash_entry["type"] != "publicKeySha1",
                event_payload["hashes"]
            )
        if "relationships" in metadata:
            event_payload["relationships"] = metadata["relationships"]

        MessageUtils.dict_to_json_payload(event, event_payload)
        self._app.client.send_event(event)
    def _get_agents(self, request, request_payload):
        hash_match_result = self._get_reputation_for_hashes(
            request_payload["hashes"])
        metadata = self.REPUTATION_METADATA[hash_match_result]

        res = Response(request)
        payload = {"agents": metadata["agents"]} if "agents" in metadata else {}
        MessageUtils.dict_to_json_payload(res, payload)
        self._app.client.send_response(res)
    def _set_item_reputation(self, request, request_payload, item_name,
                             change_topic):
        new_entry = None

        if item_name in self.REPUTATION_METADATA:
            new_reputations = self.REPUTATION_METADATA[item_name][
                "reputations"]
            for reputation_entry in new_reputations:
                if reputation_entry["providerId"] == request_payload[
                        "providerId"]:
                    new_entry = reputation_entry
        else:
            new_reputations = []
            self.REPUTATION_METADATA[item_name] = {
                "hashes": {},
                "reputations": new_reputations
            }

        old_reputations = copy.deepcopy(new_reputations)
        old_hashes = self.REPUTATION_METADATA[item_name]["hashes"]

        for hash_type, hash_value in old_hashes.items():
            if hash_type in self.hash_algos_to_files and \
                hash_value in self.hash_algos_to_files[hash_type]:
                del self.hash_algos_to_files[hash_type][hash_value]

        new_hashes = {new_hash["type"]: new_hash["value"] \
                      for new_hash in request_payload["hashes"]}
        self._set_hash_algos_for_item(item_name, new_hashes)
        self.REPUTATION_METADATA[item_name]["hashes"] = new_hashes

        if not new_entry:
            new_entry = {
                "attributes": {},
                "providerId": request_payload["providerId"]
            }
        new_entry["trustLevel"] = request_payload["trustLevel"]
        new_entry["createDate"] = int(time.time())
        new_reputations.append(new_entry)

        self._client.send_response(Response(request))

        event = Event(change_topic)
        event_payload = {
            "hashes": request_payload["hashes"],
            "oldReputations": {
                "reputations": old_reputations
            },
            "newReputations": {
                "reputations": new_reputations
            },
            "updateTime": int(time.time())
        }

        MessageUtils.dict_to_json_payload(event, event_payload)
        self._client.send_event(event)
 def on_request(self, request):
     try:
         res = Response(request)
         result = self._store_manager.store_segment(request)
         MessageUtils.dict_to_json_payload(res, result.to_dict())
         self._dxl_client.send_response(res)
     except Exception as ex:
         err_res = ErrorResponse(request,
                                 error_message=MessageUtils.encode(str(ex)))
         self._dxl_client.send_response(err_res)
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param request: The request message
        """
        # Handle request
        logger.info("Request received on topic: '%s' with payload: '%s'",
                    request.destination_topic,
                    MessageUtils.decode_payload(request))

        try:
            # API URL
            api_url = self._app.URL_VOID_API_URL_FORMAT.format(self._app.api_key)

            command = request.destination_topic[self._app.SERVICE_TYPE_LENGTH + 1:]
            params = {}
            if request.payload:
                params = MessageUtils.json_payload_to_dict(request)

            if self._required_params:
                self._validate(params)

            if command == self._app.CMD_HOST_INFO:
                host = params[self.PARAM_HOST]
                api_url = "{0}{1}/{2}".format(api_url, self.PARAM_HOST, host)
            elif command == self._app.CMD_HOST_RESCAN:
                host = params[self.PARAM_HOST]
                api_url = "{0}{1}/{2}/rescan".format(api_url, self.PARAM_HOST, host)
            elif command == self._app.CMD_HOST_SCAN:
                host = params[self.PARAM_HOST]
                api_url = "{0}{1}/{2}/scan".format(api_url, self.PARAM_HOST, host)
            elif command == self._app.CMD_STATS_REMAINED:
                api_url = "{0}{1}".format(api_url, command)

            # Invoke URLVoid API
            url_void_api_response = requests.get(api_url)

            # Check HTTP response code
            url_void_api_response.raise_for_status()

            # Create response
            res = Response(request)

            # Set payload
            MessageUtils.encode_payload(res, url_void_api_response.text)

            # Send response
            self._app.client.send_response(res)

        except Exception as ex:
            logger.exception("Error handling request")
            err_res = ErrorResponse(request, error_message=MessageUtils.encode(str(ex)))
            self._app.client.send_response(err_res)
 def on_event(self, event):
     event_payload_dict = MessageUtils.json_payload_to_dict(event)
     # Check the event payload to see if the OpenDXL event was triggered
     # by the new MISP event that the sample created.
     if "Event" in event_payload_dict and \
         "info" in event_payload_dict["Event"] and \
         event_payload_dict["Event"]["info"] == \
             "OpenDXL MISP event notification example":
         # Print the payload for the received event
         print("Received event:\n{}".format(
             MessageUtils.dict_to_json(event_payload_dict,
                                       pretty_print=True)))
    def on_request(self, request):
        """
        Invoked when a request message is received.

        :param request: The request message
        """
        # Handle request
        logger.info("Request received on topic: '%s' with payload: '%s'",
                    request.destination_topic,
                    MessageUtils.decode_payload(request))

        try:
            res = Response(request)

            request_dict = MessageUtils.json_payload_to_dict(request) \
                if request.payload else {}

            # Ensure required parameters are present
            if self._required_params:
                for name in self._required_params:
                    if name not in request_dict:
                        raise Exception(
                            "Required parameter not found: '{}'".format(name))

            if "format" not in request_dict:
                request_dict["format"] = "json"
            elif request_dict["format"] not in ("json", "xml"):
                raise Exception(
                    "Unsupported format requested: '{}'. {}".format(
                        request_dict["format"],
                        "Only 'json' and 'xml' are supported."))

            # Invoke DomainTools API via client
            dt_response = \
                getattr(self._app.domaintools_api,
                        self._func_name)(**request_dict)

            # Set response payload
            response_data = dt_response.data()
            if isinstance(response_data, dict):
                MessageUtils.dict_to_json_payload(res, response_data)
            else:
                MessageUtils.encode_payload(res, response_data)

        except ServiceException as ex:
            logger.exception("Error handling request")
            msg = "%s: %s" % (ex.__class__.__name__, ex.reason)
            res = ErrorResponse(request,
                                error_message=MessageUtils.encode(msg))

        except Exception as ex:
            logger.exception("Error handling request")
            msg = str(ex)
            if not msg:
                msg = ex.__class__.__name__
            res = ErrorResponse(request,
                                error_message=MessageUtils.encode(msg))

        # Send response
        self._app.client.send_response(res)
示例#26
0
    def on_event(self, event):
        """
        Invoked when an event is received.

        :param event: The event
        """
        # Handle event
        event_payload = MessageUtils.json_payload_to_dict(event)
        if event.destination_topic in self._callbacks:
            self._callbacks[event.destination_topic](event_payload)
        else:
            raise NotImplementedError(
                MessageUtils.encode("Unknown topic: " +
                                    event.destination_topic))
示例#27
0
 def ip_rep_cmd(parsed_url):
     ip_param = \
         urlparse.parse_qs(parsed_url.query)[ApiVoidCallback.PARAM_IP][0]
     if ip_param == SAMPLE_IP:
         return MessageUtils.dict_to_json(SAMPLE_IP_REP, pretty_print=False)
     return MockApiVoidServerRequestHandler.bad_param(
         ApiVoidCallback.PARAM_IP, ip_param)
示例#28
0
    def send_command(self, topic, command):
        """
        Sends an Open Command and Control (OpenC2) message to the
        specified DXL service and returns the response.

        The `Lycan library <https://github.com/oasis-open/openc2-lycan-python>`_
        contains the OpenC2 classes (Command, Response, etc.).

        :param topic: The DXL service topic to send the OpenC2 command to
        :param command: The `openc2.v10.Command` to send to the DXL service
        :return: The `openc2.v10.Response` received from the DXL service
        """

        # Create the DXL request message
        request = Request(topic)

        # Serialize and encode the OpenC2 command
        request.payload = command.serialize().encode()

        # Perform a synchronous DXL request
        response = self._dxl_sync_request(request)

        if response.message_type == Message.MESSAGE_TYPE_ERROR:
            raise Exception(response.error_message)

        # Return the response
        response_dict = MessageUtils.json_payload_to_dict(response)
        return openc2.v10.Response(**response_dict)
    def _generate_nmap_dict_report(self, targets, options, request):
        """
        Executes the Nmap tool to scan/analyze a list of hosts (IPs) with the specific
        (parameters) options.

        :param targets: List of hosts (IPs) to scan/analyze.
        :param options: Options required to execute Nmap tool.
        :param request: The request message.
        :return: The Nmap output information (formatted) based on the original Nmap XML report
        information.
        """

        # Create Nmap process and run it
        nmproc = NmapProcess(targets, options)

        try:
            # Run the Nmap process
            nmproc.run()

            # Generate report
            nmap_report = NmapParser.parse(nmproc.stdout)

            # Parse Nmap report
            parsed_report = self._parse_nmap_xml_report(nmap_report)

            # Return the parse  Nmap report
            return parsed_report
        except Exception as ex:
            logger.exception("Nmap scan failed: {0}".format(nmproc.stderr))
            err_res = ErrorResponse(request, MessageUtils.encode(str(ex)))
            self._app.client.send_response(err_res)
示例#30
0
 def unknown_call(path):
     return MessageUtils.dict_to_json(
         {
             "unit_test_error_unknown_api": path
         },
         pretty_print=False
     )