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 _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)
Exemple #3
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 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 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 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_all_policies(self):
        """
        Retrieve information for all ANC policies.

        :return: The policy information, which should look similar to this:

            .. code-block:: json

                {
                    "ancStatus": "success",
                    "ancpolicy": [
                        {
                            "action": [
                                "ShutDown"
                            ],
                            "name": "shutdown_policy"
                        },
                        {
                            "action": [
                                "Quarantine"
                            ],
                            "name": "quarantine_policy"
                        }
                    ]
                }
        :rtype: dict
        """
        request = Request(self._ANC_RETRIEVE_ALL_POLICIES)
        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 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
        """
        # 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 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 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))
Exemple #13
0
    def get_broker_registry(self, client_id=None):
        """
        Queries the broker for the broker registry and replaces the currently stored one with
        the new results. Notifies all connected web sockets that new broker information
        is available.
        """
        req = Request(TopologyModule.BROKER_REGISTRY_QUERY_TOPIC)

        if client_id:
            req.payload = "{ \"brokerGuid\":\"" + client_id + "\"}"
        else:
            req.payload = "{}"

        # Send the request
        dxl_response = self.app.dxl_service_client.sync_request(req, 5)

        if dxl_response.message_type == Message.MESSAGE_TYPE_ERROR:
            logger.error(
                "Error response returned from the broker registry: %s",
                dxl_response.error_message)
            return {}

        dxl_response_dict = MessageUtils.json_payload_to_dict(dxl_response)
        logger.info("Broker registry response: %s", dxl_response_dict)

        brokers = {}
        for broker_guid in dxl_response_dict["brokers"]:
            brokers[broker_guid] = dxl_response_dict["brokers"][broker_guid]

        self.current_connected_broker = dxl_response.source_broker_id

        return brokers
Exemple #14
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 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 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 _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 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)
Exemple #19
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)
Exemple #20
0
    def on_event(self, event):
        """
        Method invoked when an create policy event occurs. Derived classes can
        implement the :meth:`on_create_policy` method instead of this method in
        order to process the event payload as a `dict`.

        :param dxlclient.message.Event event: Message received for the event
            notification
        """
        self.on_create_policy(MessageUtils.json_payload_to_dict(event))
    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)))
Exemple #23
0
    def on_event(self, event):
        """
        Notifies all clients that there are changes to the broker registry

        :param event: the incoming event
        """
        fabric_change_event = MessageUtils.json_payload_to_dict(event)
        logger.info("Received broker fabric change event: %s",
                    fabric_change_event)

        # Spawn a new thread to update the broker list as it requires a DXL request
        thread = Thread(target=self._module.update_broker_registry)
        thread.start()
Exemple #24
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))
    def on_event(self, event):
        """
        Notifies all clients that there are changes to the service registry

        :param event: the incoming event
        """
        service_event = MessageUtils.json_payload_to_dict(event)
        logger.info("Received service registry event: %s", service_event)
        if event.destination_topic == MonitorModule.SERVICE_REGISTRY_REGISTER_EVENT_TOPIC:
            self._module.update_service(service_event)
        elif event.destination_topic == MonitorModule.SERVICE_REGISTRY_UNREGISTER_EVENT_TOPIC:
            self._module.remove_service(service_event)

        self._module.notify_web_sockets()
    def _invoke_mar_search_api(self, payload_dict):
        """
        Executes a query against the MAR search API

        :param payload_dict: The payload
        :return: A dictionary containing the results of the query
        """
        # Create the request message
        req = Request(MAR_SEARCH_TOPIC)
        # Set the payload
        req.payload = json.dumps(payload_dict).encode(encoding="UTF-8")

        # Display the request that is going to be sent
        logger.debug(
            "Request:\n%s",
            json.dumps(payload_dict,
                       sort_keys=True,
                       indent=4,
                       separators=(',', ': ')))

        # Send the request and wait for a response (synchronous)
        res = self._dxl_sync_request(req)

        # Return a dictionary corresponding to the response payload
        resp_dict = MessageUtils.json_payload_to_dict(res)
        # Display the response
        logger.debug(
            "Response:\n%s",
            json.dumps(resp_dict,
                       sort_keys=True,
                       indent=4,
                       separators=(',', ': ')))
        if "code" in resp_dict:
            code = resp_dict['code']
            if code < 200 or code >= 300:
                if "body" in resp_dict and "applicationErrorList" in \
                        resp_dict["body"]:
                    error = resp_dict["body"]["applicationErrorList"][0]
                    raise Exception(error["message"] + ": " +
                                    str(error["code"]))
                elif "body" in resp_dict:
                    raise Exception(resp_dict["body"] + ": " + str(code))
                else:
                    raise Exception("Error: Received failure response code: " +
                                    str(code))
        else:
            raise Exception("Error: unable to find response code")
        return resp_dict
Exemple #27
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)
Exemple #29
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)
    def _get_index_parameters(self, event):
        """
        Get parameters for an Elasticsearch 'index' operation for use in
        storing the payload from the supplied event to Elasticsearch.

        :param dxlclient.message.Event event: The event.
        :return: A dictionary with parameters for the 'index' operation. If
            the event payload cannot be converted into a JSON document or if
            the ID cannot be derived from the document, None is returned.
        :rtype: dict
        """
        body = None
        document_id = None

        try:
            body = MessageUtils.json_payload_to_dict(event)
            if self._id_field_name:
                document_id = body.get(self._id_field_name)
                if not document_id:
                    logger.error("%s from %s field in event, %s: %s",
                                 "Unable to obtain id", self._id_field_name,
                                 "skipping indexing for topic",
                                 event.destination_topic)
        except ValueError:
            if self._transform_script:
                body = event.payload
            else:
                logger.error("%s, skipping indexing for topic: %s",
                             "Unable to parse event payload as JSON",
                             event.destination_topic)

        if body:
            index_parameters = {
                "index": self._document_index,
                "doc_type": self._document_type,
                "body": body,
                "id": document_id
            }
        else:
            index_parameters = None

        return index_parameters