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
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()
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")
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) + ")")
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
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) + ")")
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 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
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)
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)
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.")
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()
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
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)
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")
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" +
# 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()
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()
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
# 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) + ")")
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()