diff --git a/domaintools_iris.json b/domaintools_iris.json index 18498e8..4d8f7ca 100644 --- a/domaintools_iris.json +++ b/domaintools_iris.json @@ -2438,6 +2438,124 @@ } ], "versions": "EQ(*)" + }, + { + "action": "domain rdap feed", + "description": "List of records for a given domain may be provided by a domain registry, registrar, or both. Domain registries maintain authoritative information about one or more top-level domains (e.g., .com), while domain registrars manage apex domains (e.g., domaintools.com). When domain information is present from both the registry and registrar, this API presents a record containing both sets of results, as well the original raw JSON record, from both the registry and registrar.", + "type": "investigate", + "identifier": "parsed_domain_rdap_feed", + "read_only": true, + "parameters": { + "domain": { + "description": "Used to filter feed results. The filter can be an exact match or a partial match when the * character is included at the beginning and/or end of the value.", + "data_type": "string", + "order": 0 + }, + "before": { + "description": "The end of the query window in seconds or in ISO8601 format, relative to the current time, inclusive.", + "data_type": "string", + "order": 1 + }, + "after": { + "description": "The start of the query window in seconds in ISO8601 format, relative to the current time, inclusive.", + "data_type": "string", + "order": 2 + }, + "session_id": { + "description": "Serves as a unique identifier for the session. This parameter ensures that data retrieval begins from the latest timestamp recorded in the previous data pull.", + "data_type": "string", + "order": 3 + }, + "top": { + "description": "The number of results to return in the response payload. Primarily used for testing.", + "data_type": "string", + "order": 4 + } + }, + "render": { + "width": 12, + "title": "Parsed Domain RDAP List", + "type": "table", + "height": 10 + }, + "output": [ + { + "data_path": "action_result.data", + "data_type": "string" + }, + { + "data_path": "action_result.data.*.domain", + "data_type": "string", + "column_name": "Domain Names", + "column_order": 0, + "contains": [ + "domain" + ] + }, + { + "data_path": "action_result.data.*.timestamp", + "data_type": "string", + "column_name": "Time Stamp", + "column_order": 1 + }, + { + "data_path": "action_result.data.*.parsed_record.parsed_fields", + "data_type": "string", + "column_name": "Parsed Record", + "column_order": 2 + }, + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.after", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.before", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.domain", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.session_id", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.top", + "data_type": "string" + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric", + "example_values": [ + 1 + ] + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric", + "example_values": [ + 1 + ] + } + ], + "versions": "EQ(*)" } ], "pip39_dependencies": { diff --git a/domaintools_iris_connector.py b/domaintools_iris_connector.py index 733bc11..7e5b6f9 100644 --- a/domaintools_iris_connector.py +++ b/domaintools_iris_connector.py @@ -38,7 +38,8 @@ class DomainToolsConnector(BaseConnector): ACTION_ID_NOD_FEED = "nod_feed" ACTION_ID_NAD_FEED = "nad_feed" ACTION_ID_DOMAIN_DISCOVERY_FEED = "domain_discovery_feed" - RTUF_SERVICES_LIST = ["nod", "nad", "domaindiscovery"] + ACTION_ID_PARSED_DOMAIN_RDAP_FEED = "parsed_domain_rdap_feed" + RTUF_SERVICES_LIST = ["nod", "nad", "domaindiscovery", "domainrdap"] def __init__(self): # Call the BaseConnectors init first @@ -65,6 +66,7 @@ def __init__(self): self.ACTION_ID_NOD_FEED: self._nod_feed, self.ACTION_ID_NAD_FEED: self._nad_feed, self.ACTION_ID_DOMAIN_DISCOVERY_FEED: self._domain_discovery_feed, + self.ACTION_ID_PARSED_DOMAIN_RDAP_FEED: self._parsed_domain_rdap_feed, } def initialize(self): @@ -130,14 +132,7 @@ def _parse_feeds_response(self, service, action_result, feeds_results): rows = response.strip().split("\n") for row in rows: - if service in self.RTUF_SERVICES_LIST: - feed_result = json.loads(row) - data.append( - { - "timestamp": feed_result.get("timestamp"), - "domain": feed_result.get("domain"), - } - ) + data.append(json.loads(row)) action_result.update_data(data) except Exception as error: @@ -867,16 +862,12 @@ def _configure_monitoring_scheduled_playbooks(self, param): ) def _nod_feed(self, param): - self.save_progress("Starting nod_feed action.") + self.save_progress(f"Starting {self.ACTION_ID_NOD_FEED} action.") action_result = self.add_action_result(ActionResult(param)) - params = {"always_sign_api_key": False} - params.update(param) - session_id = params.pop("session_id", None) - if session_id: - params["sessionID"] = session_id + params = self._get_rtuf_actions_params(param) ret_val = self._do_query("nod", action_result, query_args=params) - self.save_progress("Completed nod_feed action.") + self.save_progress(f"Completed {self.ACTION_ID_NOD_FEED} action.") if not ret_val: return action_result.get_data() @@ -884,16 +875,12 @@ def _nod_feed(self, param): return action_result.get_status() def _nad_feed(self, param): - self.save_progress("Starting nad_feed action.") + self.save_progress(f"Starting {self.ACTION_ID_NAD_FEED} action.") action_result = self.add_action_result(ActionResult(param)) - params = {"always_sign_api_key": False} - params.update(param) - session_id = params.pop("session_id", None) - if session_id: - params["sessionID"] = session_id + params = self._get_rtuf_actions_params(param) ret_val = self._do_query("nad", action_result, query_args=params) - self.save_progress("Completed nad_feed action.") + self.save_progress(f"Completed {self.ACTION_ID_NAD_FEED} action.") if not ret_val: return action_result.get_data() @@ -903,11 +890,7 @@ def _nad_feed(self, param): def _domain_discovery_feed(self, param): self.save_progress(f"Starting {self.ACTION_ID_DOMAIN_DISCOVERY_FEED} action.") action_result = self.add_action_result(ActionResult(param)) - params = {"always_sign_api_key": False} - params.update(param) - session_id = params.pop("session_id", None) - if session_id: - params["sessionID"] = session_id + params = self._get_rtuf_actions_params(param) ret_val = self._do_query("domaindiscovery", action_result, query_args=params) self.save_progress(f"Completed {self.ACTION_ID_DOMAIN_DISCOVERY_FEED} action.") @@ -917,6 +900,28 @@ def _domain_discovery_feed(self, param): return action_result.get_status() + def _parsed_domain_rdap_feed(self, param): + self.save_progress(f"Starting {self.ACTION_ID_PARSED_DOMAIN_RDAP_FEED} action.") + action_result = self.add_action_result(ActionResult(param)) + params = self._get_rtuf_actions_params(param) + + ret_val = self._do_query("domainrdap", action_result, query_args=params) + self.save_progress(f"Completed {self.ACTION_ID_PARSED_DOMAIN_RDAP_FEED} action.") + + if not ret_val: + return action_result.get_data() + + return action_result.get_status() + + def _get_rtuf_actions_params(self, param): + params = {"always_sign_api_key": False} + params.update(param) + session_id = params.pop("session_id", None) + if session_id: + params["sessionID"] = session_id + + return params + if __name__ == "__main__": import argparse