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 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 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 _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 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 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)
    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
Exemple #9
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 _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
        logger.info("Request received on topic: '{0}' with payload: '{1}'".format(
            request.destination_topic, MessageUtils.decode_payload(request)))

        try:
            # Parameters
            nmap_params = MessageUtils.json_payload_to_dict(request)

            logger.info("[1/2] Requested NMAP action ({0}) for request {1} is under processing...".format(
                MessageUtils.decode_payload(request), request.message_id))
            # Create a report from Nmap tool execution
            nmap_response = self._do_nmap_scan(nmap_params, request)
            logger.info("[2/2] Requested NMAP action was processed successfully for request {0}."
                        " Preparing response...".format(request.message_id))

            # Create response
            res = Response(request)

            # Set payload
            MessageUtils.dict_to_json_payload(res, nmap_response)

            # Send response
            self._app.client.send_response(res)
            logger.info("Sending response for request {0}".format(request.message_id))

        except Exception as ex:
            logger.exception("Error handling request")
            err_res = ErrorResponse(request, MessageUtils.encode(str(ex)))
            self._app.client.send_response(err_res)
    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 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))
    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 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)
    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)
    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,
                             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 _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 _get_item_first_instance(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)

        if "agents" in metadata:
            payload = {
                "totalCount": len(metadata["agents"]),
                "agents": metadata["agents"]
            }
        else:
            payload = {}

        MessageUtils.dict_to_json_payload(res, payload)
        self._client.send_response(res)
Exemple #22
0
    def _invoke_service(self, request_method, request_dict):
        """
        Invokes a request method on the Elasticsearch 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._elasticsearch_service_unique_id:
            request_service_id = "/{}".format(
                self._elasticsearch_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_client.sync_request(request,
                                                 timeout=self.response_timeout)

        if response.message_type == Message.MESSAGE_TYPE_ERROR:
            try:
                self._raise_exception_for_error_response(
                    MessageUtils.json_payload_to_dict(response))
            except ValueError:
                # If an appropriate exception cannot be constructed from the
                # error response data, raise a more generic Exception as a
                # fallback.
                raise Exception("Error: {} ({})".format(
                    response.error_message,
                    str(response.error_code)))

        # Convert the JSON payload in the DXL response message to a Python
        # dictionary and return it.
        return MessageUtils.json_payload_to_dict(response)
    def _get_reputation(self, request, request_payload):
        hash_match_result = self._get_reputation_for_hashes(
            request_payload["hashes"])

        res = Response(request)

        payload = {
            "props": {
                "serverTime": int(time.time()),
                "submitMetaData": 1
            },
            "reputations":
            self.REPUTATION_METADATA[hash_match_result]["reputations"],
        }

        MessageUtils.dict_to_json_payload(res, payload)

        self._client.send_response(res)
Exemple #24
0
    def test_callback_urlscan(self):
        with MockServerRunner() as server_runner, \
            VirusTotalApiService(TEST_FOLDER) as vt_service:

            vt_service.VTAPI_URL_FORMAT = "http://127.0.0.1:" \
                                          + str(server_runner.mock_server_port) \
                                          + "/vtapi/v2{0}"
            vt_service.run()

            request_topic = VirusTotalApiService.REQ_TOPIC_URL_SCAN
            req = Request(request_topic)
            MessageUtils.dict_to_json_payload(
                req, {VirusTotalApiRequestCallback.PARAM_URL: SAMPLE_URL})

            res = vt_service._dxl_client.sync_request(req, timeout=30)
            res_dict = MessageUtils.json_payload_to_dict(res)

            self.assertDictEqual(SAMPLE_URL_SCAN, res_dict)
    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:
            # Retrieve the parameters from the request
            params = MessageUtils.json_payload_to_dict(request)

            if self._PARAM_HOST not in params:
                raise Exception(
                    "Required parameter not specified: '{0}'".format(
                        self._PARAM_HOST))

            target = params[self._PARAM_HOST]

            ipaddr = socket.gethostbyname(target)

            logger.debug("IP to be located: %s", ipaddr)
            # Lookup the IP/host
            results = self._app.database.lookup_ip(ipaddr)
            logger.debug(results)

            # Create response
            res = Response(request)

            # Set payload
            MessageUtils.dict_to_json_payload(res, results)

            # 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 _build_http_error_response(dxl_request, response):
        """
        Create a DXL ErrorResponse from the contents of an HTTP response
        for a request sent to TheHive.

        :param dxlclient.message.Request dxl_request: DXL request containing
            parameters to forward along in a request to TheHive server.
        :param requests.Response response: HTTP response received from TheHive.
        :return: The error response to deliver to the DXL fabric.
        :rtype: dxlclient.message.ErrorResponse
        """
        response_dict = response.json()
        error_message = response_dict.get("message")
        if not error_message:
            errors = response_dict.get("errors")
            if errors:
                first_error = errors[0]
                if isinstance(first_error, dict):
                    error_message = first_error.get("message")
                elif isinstance(first_error, list):
                    first_suberror = first_error[0]
                    if isinstance(first_suberror, dict):
                        error_message = first_suberror.get(
                            "message")
        if error_message:
            log_message = "Error handling request: {}".format(
                error_message
            )
        else:
            # Short error message could not be read from the
            # response body, so just set a generic description for
            # the error message in the DXL response.
            error_message = "Error handling request"
            log_message = error_message
        logger.error(log_message)
        res = ErrorResponse(
            dxl_request,
            error_message=error_message \
                if error_message else "Error handling request",
            error_code=response.status_code
        )
        MessageUtils.dict_to_json_payload(res, response_dict)
        return res
Exemple #27
0
    def lookup_host(self, host):
        """
        Looks up Geolocation information for the specified host/IP

        :param host: The host/IP to lookup
        :return: A dictionary (``dict``) containing the details of the Geolocation lookup
        """
        # Create the DXL request message
        request = Request(self.HOST_LOOKUP_TOPIC)

        # Set the payload on the request message (Python dictionary to JSON payload)
        MessageUtils.dict_to_json_payload(request, {self._PARAM_HOST: host})

        # 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)
Exemple #28
0
    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)
        return dxl_client.sync_request(request, timeout=response_timeout)
    def clear_endpoint_policy_by_mac(self, mac_address):
        """
        Clear the policy for an endpoint by its MAC address.

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

            .. code-block:: json

                {
                    "ancStatus": "success"
                }
        :rtype: dict
        :raises Exception: If no policy has been associated with the endpoint.
        """
        request = Request(self._ANC_CLEAR_ENDPOINT_POLICY_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))
Exemple #30
0
    def _invoke_service(self, req_dict, topic):
        """
        Invokes the DXL Nmap service.

        :param req_dict: Dictionary containing request information
        :param topic: The Nmap DXL topic to invoke
        :return: A dictionary containing the response
        """
        # Create the DXL request message
        request = Request(topic)

        # Set the payload on the request message (Python dictionary to JSON
        # payload)
        MessageUtils.dict_to_json_payload(request, req_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)