コード例 #1
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
コード例 #2
0
    def send_unregister_service_event(self):
        """
        Send the unregister event for the service.

        :return: None.
        """
        if not self.client:
            raise DxlException("Client not defined")
        with self.lock:
            # Send the unregister event only if the register event was sent before and TTL has not yet expired.
            current_time = int(time.time())
            last_register_time = self.get_register_time()

            if last_register_time > 0 and (
                    current_time - last_register_time) <= (self.ttl * 60):
                request = Request(destination_topic=_ServiceManager.
                                  DXL_SERVICE_UNREGISTER_REQUEST_CHANNEL)
                request.payload = self.json_unregister_service()
                response = self.client.sync_request(request, timeout=60)
                if response.message_type == Message.MESSAGE_TYPE_ERROR:
                    raise DxlException("Unregister service request timed out")
            else:
                if last_register_time > 0:
                    # pylint: disable=logging-not-lazy
                    logger.info(
                        "TTL expired, unregister service event omitted for " +
                        self.service_type + " (" + self.instance_id + ")")
            info = self.service
            if info:
                info._notify_unregistration_succeeded()
コード例 #3
0
    def send_unregister_service_event(self):
        """
        Send the unregister event for the service.
        
        :return: None.
        """
        if not self.client:
            raise DxlException("Client not defined")
        # Send the unregister event only if the register event was sent before and TTL has not yet expired.
        current_time = int(time.time())
        last_register_time = self.get_register_time()

        if last_register_time > 0 and (current_time -
                                       last_register_time) <= (self.ttl * 60):
            request = Request(destination_topic=_ServiceManager.
                              DXL_SERVICE_UNREGISTER_REQUEST_CHANNEL)
            request.payload = bytes(self.json_unregister_service())
            response = self.client.sync_request(request, timeout=60)
            if response.message_type != Message.MESSAGE_TYPE_ERROR:
                info = self.get_service()
                if info:
                    info._notify_unregistration_succeeded()
            else:
                raise DxlException("Unregister service request timed out")
        else:
            raise DxlException("Unregister service request timed out")
コード例 #4
0
def execute_mar_search_api(client, payload_dict):
    """
    Executes a query against the MAR search api

    :param client: The DXL client
    :param payload_dict: The payload
    :return: A dictionary containing the results of the query
    """
    # Create the request message
    req = Request(CREATE_SEARCH_TOPIC)
    # Set the payload
    req.payload = json.dumps(payload_dict).encode()

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

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

    # Return a dictionary corresponding to the response payload
    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        resp_dict = json.loads(res.payload.decode())
        # Display the response
        print "Response:\n" + 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:
                raise Exception("Error: Received failure response code: " + str(code))
        else:
            raise Exception("Error: unable to find response code")
        return resp_dict
    else:
        raise Exception("Error: " + res.error_message + " (" + str(res.error_code) + ")")
コード例 #5
0
 def ticket(self, msg):
     print "Filing ticket..."
     req = Request(SERVICE_TOPIC)
     req.payload = msg
     res = client.sync_request(req)
     if res.message_type != Message.MESSAGE_TYPE_ERROR:
         print "Create Ticket Number %s" % res
コード例 #6
0
def get_tie_file_reputation(client, md5_hex, sha1_hex):
    """
    Returns a dictionary containing the results of a TIE file reputation request

    :param client: The DXL client
    :param md5_hex: The MD5 Hex string for the file
    :param sha1_hex: The SHA-1 Hex string for the file
    :return: A dictionary containing the results of a TIE file reputation request
    """
    # Create the request message
    req = Request(FILE_REP_TOPIC)

    # Create a dictionary for the payload
    payload_dict = {
        "hashes": [{
            "type": "md5",
            "value": base64_from_hex(md5_hex)
        }, {
            "type": "sha1",
            "value": base64_from_hex(sha1_hex)
        }]
    }

    # Set the payload
    req.payload = json.dumps(payload_dict).encode()

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

    # Return a dictionary corresponding to the response payload
    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        return json.loads(res.payload.decode(encoding="UTF-8"))
    else:
        raise Exception("Error: " + res.error_message + " (" +
                        str(res.error_code) + ")")
コード例 #7
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)
コード例 #8
0
ファイル: manager.py プロジェクト: ekmixon/scap-v2-prototype
    def query_repository(query):
        # Create query message and send it to the repository
        req = Request(SERVICE_REPOSITORY_QUERY_TOPIC)
        qm = QueryMessage(query)
        req.payload = (qm.to_json()).encode()
        res = client.sync_request(req)

        # Parse and return the query results
        qrm = QueryResultMessage()
        qrm.parse(res.payload.decode())
        return qrm
コード例 #9
0
def main(argv):
    TOPIC_DESTINATION = ''
    TYPE_PAYLOAD = ''
    PAYLOAD = ''
    help = 'python ' + sys.argv[0] + ' -t <topic destination> -p <payload>'

    try:
        opts, args = getopt.getopt(argv, "ht:p:", ["topic=", "payload="])
    except getopt.GetoptError:
        print help
        sys.exit(1)

    for opt, arg in opts:
        if opt == '-h':
            print help
            sys.exit(1)
        elif opt in ("-t", "--topic"):
            TOPIC_DESTINATION = arg
        elif opt in ("-p", "--payload"):
            PAYLOAD = arg

    if (TOPIC_DESTINATION != '' and PAYLOAD != ''):

        DXL_MESSAGE['SRC_HOST'] = IP
        DXL_MESSAGE['PAYLOAD'] = PAYLOAD

        # Create the client
        with DxlClient(config) as client:

            # Connect to the fabric
            client.connect()
            #
            # Invoke the service (send a request)
            #
            # Create the request
            req = Request(TOPIC_DESTINATION)
            # Populate the request payload
            req.payload = str(json.dumps(DXL_MESSAGE)).encode()

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

            # Extract information from the response (if an error did not occur)
            if res.message_type != Message.MESSAGE_TYPE_ERROR:
                print "result is coming:"
                print res.payload
            else:
                logger.error("Error: " + res.error_message + " (" +
                             str(res.error_code) + ")")

    else:
        print help
        sys.exit(1)
コード例 #10
0
    def request_assessment(iam):
        # Create a report request and send it to the manager
        req = Request(SERVICE_INITIATE_ASSESSMENT_TOPIC)
        req.payload = (iam.to_json()).encode()
        logger.info("Requesting report for %s:", iam.to_s())
        res = client.sync_request(req)

        # Extract and store the transaction id from the acknowledgement message
        if res.message_type != Message.MESSAGE_TYPE_ERROR:
            ram = RequestAcknowledgementMessage()
            ram.parse(res.payload.decode())
            logger.info("Application received response: %s", ram.to_s())
            transactions.append(ram.transaction_id)
コード例 #11
0
    def send_register_service_request(self):
        """
        Send the registration request for the service.
        
        :return: None.
        """
        if not self.client:
            raise DxlException("Client not defined")
        req = Request(destination_topic=_ServiceManager.DXL_SERVICE_REGISTER_REQUEST_CHANNEL)
        req.payload = bytes(self.json_register_service())
        response = self.client.sync_request(req, timeout=10)

        if response.message_type != Message.MESSAGE_TYPE_ERROR:
            self.update_register_time()
            info = self.get_service()
            if info:
                info._notify_registration_succeeded()
        else:
            # TODO: Notify the client with an exception if an error occurred, so that it doesn't wait for timeout
            logger.error("Error registering service.")
コード例 #12
0
    def _refresh_all_services(self):
        """
        Queries the broker for the service list and replaces the currently stored one with the new
        results. Notifies all connected web sockets that new services are available.
        """
        req = Request(MonitorModule.SERVICE_REGISTRY_QUERY_TOPIC)

        req.payload = "{}"
        # Send the request
        dxl_response = self._dxl_service_client.sync_request(req, 5)
        dxl_response_dict = MessageUtils.json_payload_to_dict(dxl_response)
        logger.info("Service registry response: %s", dxl_response_dict)

        with self._service_dict_lock:
            self._services = {}
            for service_guid in dxl_response_dict["services"]:
                self._services[service_guid] = dxl_response_dict["services"][
                    service_guid]

        self.notify_web_sockets()
コード例 #13
0
    def task_pce(crm, pce_id):
        logger.info("Tasking PCE: %s", crm.to_s())

        # Get content and perform any content conversions
        # before sending to PCE. If cancellation message
        # just send that to the PCE.
        if crm.ids == "":
            content = "cancel_" + str(crm.transaction_id)
        else:
            content = get_content(crm.ids)
            content = convert_content(content)

        # Send the collection request to the identified PCE
        req = Request(SERVICE_PCE_REQUEST_TOPIC + "/" + pce_id)
        req.payload = content
        res = client.sync_request(req)

        if res.message_type != Message.MESSAGE_TYPE_ERROR:
            # Only send results if not a cancel message
            if crm.ids != "":
                rrsm = ReportResultsMessage()
                rrsm.assessment_results = res.payload.decode()
                rrsm.transaction_id = crm.transaction_id
                rrsm.requestor_id = crm.requestor_id
                rrsm.target_id = lookup_target_id(pce_id)
                rrsm.collector_id = COLLECTOR_ID
                rrsm.pcx_id = PCX_ID
                rrsm.pce_id = pce_id
                rrsm.timestamp = str(datetime.datetime.now())

                # Apply collection parameters
                cp_rrsm = apply_collection_parameters(
                    rrsm, crm.collection_parameters)
                store_data(cp_rrsm)

                # Apply result format and filters and send to the
                # appropriate application
                rff_rrsm = apply_format_and_filters(rrsm,
                                                    crm.result_format_filters)
                send_collection_results_event(rff_rrsm)
        return
コード例 #14
0
    def _invoke_service(self, topic, payload, other_fields=None):
        """
        Invokes a request method on the File Transfer DXL service.

        :param str topic: The topic to send the request to.
        :param payload: The payload to include in the request
        :param dict other_fields: Other fields to include in the request
        :return: Results of the service invocation.
        :rtype: dict
        """
        # Create the DXL request message.
        request = Request(topic)

        # Set the full request parameters.
        request.payload = payload
        request.other_fields = other_fields

        # 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)
コード例 #15
0
    def sendMessage(self, topic="/dsa/dxl/test/event2", message="Default message"):
        if not self.isConnected():
            raise DxlJythonException(1200, "Not connected to a OpenDXL broker")
        
        try:
            request = Request(topic)

            # Encode string payload as UTF-8
            request.payload = message.encode()

            # Send Synchronous Request with default timeout and wait for Response
            logger.info("Requesting '" + message + "' from '" + topic + "'")
            response = self.client.sync_request(request)

            dxl_message = JavaDxlMessage()
            dxl_message.setMessageVersion(response.version)
            dxl_message.setMessageId(response.message_id)
            dxl_message.setClientId(response.source_client_id)
            dxl_message.setBrokerId(response.source_broker_id)
            dxl_message.setMessageType(response.message_type)
            dxl_message.setBrokerIdList(response.broker_ids)
            dxl_message.setClientIdList(response.client_ids)
            dxl_message.setRequestMessageId(response.request_message_id)
                
            # Check that the Response is not an Error Response, then extract
            if response.message_type != Message.MESSAGE_TYPE_ERROR:
                dxl_message.setServiceId(response.service_id)
                dxl_message.setPayload(response.payload.decode())
            else:
                dxl_message.setErrorCode(response.error_code)
                dxl_message.setErrorMessage(response.error_message)
                
            return dxl_message
            
        except Exception as e:
            logger.info("Exception: " + e.message)
            raise DxlJythonException(1010, "Unable to communicate with a DXL broker")
コード例 #16
0
            print("   Press 1 to send a Synchronous Request")
            print("   Press 2 to send an Asynchronous Request")
            print("   Press 9 to quit")
            option = prompt("   Enter value: ").strip()

            # Option: Synchronous DXL Request
            if option == "1":
                # Create the Request
                logger.info(
                    "Service Invoker - Creating Synchronous Request for topic %s",
                    SERVICE_TOPIC)
                request = Request(SERVICE_TOPIC)

                # Encode string payload as UTF-8
                request.payload = \
                    ("Sample Synchronous Request Payload - Request ID: " +
                     str(request.message_id)).encode()

                # Send Synchronous Request with default timeout and wait for
                # Response
                logger.info(
                    "Service Invoker - Sending Synchronous Request to %s",
                    SERVICE_TOPIC)
                response = client.sync_request(request)

                # Check that the Response is not an Error Response, then extract
                if response.message_type != Message.MESSAGE_TYPE_ERROR:
                    # Extract information from Response payload, in this sample
                    # we expect it is UTF-8 encoded
                    logger.info(
                        "Service Invoker - Synchronous Response received:\n" +
コード例 #17
0
# The total number of events to send
TOTAL_EVENTS = 10

# Condition/lock used to protect changes to counter
event_count_condition = Condition()

# The events received (use an array so we can modify in callback)
event_count = [0]

# Create DXL configuration from file
config = DxlClientConfig.create_dxl_config_from_file(CONFIG_FILE)

# Create the client
with DxlClient(config) as client:

    # Connect to the fabric
    client.connect()

    #
    # Register callback and subscribe
    #

    # Create and add event listener
    req = Request(SERVICE_TOPIC)

    req.payload = "Rosamund Pike".encode()

    res = client.sync_request(req)

    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        print "Client Recieved response payload: " + res.payload.decode()
コード例 #18
0
            res = Response(request)
            # Populate the response payload
            res.payload = "pong".encode()
            # Send the response
            client.send_response(res)

    # Create service registration object
    info = ServiceRegistrationInfo(client, "myService")

    # Add a topic for the service to respond to
    info.add_topic(SERVICE_TOPIC, MyRequestCallback())

    # Register the service with the fabric (wait up to 10 seconds for registration to complete)
    client.register_service_sync(info, 10)

    #
    # Invoke the service (send a request)
    #

    # Create the request message
    req = Request(SERVICE_TOPIC)

    # Populate the request payload
    req.payload = "ping".encode()

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

    # Extract information from the response (if an error did not occur)
    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        print "Client received response payload: " + res.payload.decode()
コード例 #19
0
            m = InitiateAssessmentMessage(
                "assess", "os == Ubuntu 20.04", "<= 3 days", "06-15-2020",
                "true",
                "[{\"pce-id\": \"1fe4dc4a-37a6-4787-a47a-e27f28b08e43\", \"check-type\": \"oval\"}]",
                "oval", "full", "", APP_ID)
            request_assessment(m)

        # Cancel an assessment
        elif option == "7":
            # Send a cancel request to the manager
            req = Request(SERVICE_CANCEL_ASSESSMENT_TOPIC)
            print("Available assessments:")
            print(transactions)
            transaction_id = prompt("Enter transaction id: ").strip()
            m = CancelAssessmentMessage(transaction_id, APP_ID)
            req.payload = (m.to_json()).encode()
            res = client.sync_request(req)

            if res.message_type != Message.MESSAGE_TYPE_ERROR:
                ram = RequestAcknowledgementMessage()
                ram.parse(res.payload.decode())
                logger.info("Application received response: %s", ram.to_s())

        # Query the repository
        elif option == "8":
            # Send a query request to the manager with the imaginary
            # query "my new query"
            qrm = query_repository("special_query")
            display_query_results(qrm)

        # Quit the application
コード例 #20
0
# Create the client
with DxlClient(config) as client:

    # Connect to the fabric
    client.connect()

    #
    # Invoke the service (send a request)
    #

    # Create the "Current Weather" request
    req = Request(SERVICE_CURRENT_WEATHER_TOPIC)
    # Populate the request payload
    # Examples include:
    #   By ZIP code: zip=97140,us
    #   By geographic coordinates: lat=35&lon=139
    #   By city name: q=London,uk
    req.payload = "zip=97140,us".encode()

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

    # Extract information from the response (if an error did not occur)
    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        response_dict = json.loads(res.payload.decode(encoding="UTF-8"))
        print "Client received response payload: \n" + \
          json.dumps(response_dict, sort_keys=True, indent=4, separators=(',', ': '))
    else:
        logger.error("Error: " + res.error_message + " (" +
                     str(res.error_code) + ")")
コード例 #21
0
    command = args.command

#Setup Logging
log_formatter = logging.Formatter(
    '%(asctime)s %(name)s - %(levelname)s - %(message)s')
console_handler = logging.StreamHandler()
console_handler.setFormatter(log_formatter)
logger = logging.getLogger()
logger.addHandler(console_handler)
logger.setLevel(logging.INFO)
logging.getLogger().setLevel(logging.ERROR)
logger = logging.getLogger(__name__)

#[CONFIG OPTIONS]#
SERVICE_TOPIC = "/studentname/nc/service/nc"
CONFIG_FILE = "/usr/local/etc/opendxl/dxlclient.config"

config = DxlClientConfig.create_dxl_config_from_file(CONFIG_FILE)

with DxlClient(config) as client:
    client.connect()
    # Create the request message
    req = Request(SERVICE_TOPIC)
    # Populate the request payload
    req.payload = command.encode()
    # Send the request and wait for a response (synchronous)
    res = client.sync_request(req)
    # Extract information from the response (if an error did not occur)
    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        print "Client received response payload: \n" + res.payload.decode()
config = DxlClientConfig.create_dxl_config_from_file(CONFIG_FILE)

# The ePO unique identifier
EPO_UNIQUE_ID = "<specify-ePO-unique-identifier>"

# The search text
SEARCH_TEXT = "<specify-find-search-text>"

# Create the client
with DxlClient(config) as client:

    # Connect to the fabric
    client.connect()

    req = Request("/mcafee/service/epo/remote/{0}".format(EPO_UNIQUE_ID))

    req.payload = \
        json.dumps({
            "command": "system.find",
            "output": "json",
            "params": {"searchText": SEARCH_TEXT}
        }).encode(encoding="utf-8")

    # Send the request
    res = client.sync_request(req, timeout=30)
    if res.message_type != Message.MESSAGE_TYPE_ERROR:
        response_dict = json.loads(res.payload, encoding='utf-8')
        print json.dumps(response_dict, sort_keys=True, indent=4, separators=(',', ': '))
    else:
        print "Error: {0} ({1}) ".format(res.error_message, str(res.error_code))
            # If all of the bytes in the local file have been read, this must
            # be the last segment. Send a 'store' result, file 'name', and
            # 'size' and sha256 'hash' values that the service can use to
            # confirm that the full contents of the file were transmitted
            # properly.
            bytes_read += len(segment)
            if bytes_read == file_size:
                other_fields[FileStoreProp.NAME] = os.path.join(
                    STORE_FILE_DIR, os.path.basename(STORE_FILE_NAME))
                other_fields[FileStoreProp.RESULT] = FileStoreResultProp.STORE
                other_fields[FileStoreProp.SIZE] = str(file_size)
                other_fields[FileStoreProp.HASH_SHA256] = file_hash.hexdigest()

            # Set the full request parameters
            req.other_fields = other_fields
            req.payload = segment

            # Send the file segment request to the DXL fabric. Exit if an
            # error response is received.
            res = client.sync_request(req, timeout=30)
            if res.message_type == Message.MESSAGE_TYPE_ERROR:
                print(
                    "\nError invoking service with topic '{}': {} ({})".format(
                        request_topic, res.error_message, res.error_code))
                exit(1)

            # Update the current percent complete on the console.
            sys.stdout.write("\rPercent complete: {}%".format(
                int((segment_number / total_segments) *
                    100) if total_segments else 100))
            sys.stdout.flush()