Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions domaintools_iris.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
61 changes: 33 additions & 28 deletions domaintools_iris_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -867,33 +862,25 @@ 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()

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()
Expand All @@ -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.")
Expand All @@ -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
Expand Down
Loading