-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update bundle adapter for the pipeline (#141)
- Loading branch information
1 parent
af4ea90
commit 05ec3f6
Showing
10 changed files
with
146 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 0 additions & 21 deletions
21
stix_shifter/stix_translation/src/modules/bundle/bundle_translator.py
This file was deleted.
Oops, something went wrong.
File renamed without changes.
39 changes: 39 additions & 0 deletions
39
stix_shifter/stix_translation/src/modules/stix_bundle/stix_bundle_translator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from ..base.base_translator import BaseTranslator | ||
import json | ||
import requests | ||
import re | ||
import uuid | ||
|
||
START_STOP_PATTERN = "\s?START\s?t'\d{4}(-\d{2}){2}T\d{2}(:\d{2}){2}(\.\d+)?Z'\sSTOP\s?t'\d{4}(-\d{2}){2}T(\d{2}:){2}\d{2}.\d{1,3}Z'\s?" | ||
|
||
|
||
class Translator(BaseTranslator): | ||
def transform_query(self, data, antlr_parsing_object={}, data_model_mapper={}, options={}, mapping=None): | ||
# Data is a STIX pattern. | ||
# stix2-matcher will break on START STOP qualifiers so remove before returning pattern. | ||
# Remove this when ever stix2-matcher supports proper qualifier timestamps | ||
data = re.sub(START_STOP_PATTERN, " ", data) | ||
return data | ||
|
||
def translate_results(self, data_source, data, options, mapping=None): | ||
# Wrap data in a STIX bundle and insert the data_source identity object as the first object | ||
bundle = { | ||
"type": "bundle", | ||
"id": "bundle--" + str(uuid.uuid4()), | ||
"objects": [] | ||
} | ||
|
||
data_source = json.loads(data_source) | ||
bundle['objects'] += [data_source] | ||
# Data is already STIX and we don't want to touch it | ||
bundle_data = json.loads(data) | ||
|
||
for obs in bundle_data: | ||
obs["created_by_ref"] = data_source['id'] | ||
|
||
bundle['objects'] += bundle_data | ||
return json.dumps(bundle, indent=4, sort_keys=False) | ||
|
||
def __init__(self): | ||
self.result_translator = self | ||
self.query_translator = self |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 0 additions & 73 deletions
73
stix_shifter/stix_transmission/src/modules/bundle/bundle_connector.py
This file was deleted.
Oops, something went wrong.
File renamed without changes.
100 changes: 100 additions & 0 deletions
100
stix_shifter/stix_transmission/src/modules/stix_bundle/stix_bundle_connector.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
from ..base.base_connector import BaseConnector | ||
|
||
from stix2matcher.matcher import Pattern | ||
from stix2matcher.matcher import MatchListener | ||
from stix2validator import validate_instance | ||
import json | ||
import requests | ||
from .....utils.error_response import ErrorResponder | ||
|
||
|
||
class UnexpectedResponseException(Exception): | ||
pass | ||
|
||
|
||
class Connector(BaseConnector): | ||
def __init__(self, connection, configuration): | ||
|
||
self.is_async = False | ||
self.connection = connection | ||
self.configuration = configuration | ||
self.results_connector = self | ||
self.query_connector = self | ||
self.ping_connector = self | ||
self.status_connector = self | ||
|
||
# We re-implement this method so we can fetch all the "bindings", as their method only | ||
# returns the first for some reason | ||
def match(self, pattern, observed_data_sdos, verbose=False): | ||
compiled_pattern = Pattern(pattern) | ||
matcher = MatchListener(observed_data_sdos, verbose) | ||
compiled_pattern.walk(matcher) | ||
|
||
found_bindings = matcher.matched() | ||
|
||
if found_bindings: | ||
matching_sdos = [] | ||
for binding in found_bindings: | ||
matching_sdos = matching_sdos + matcher.get_sdos_from_binding(binding) | ||
else: | ||
matching_sdos = [] | ||
|
||
return matching_sdos | ||
|
||
def ping(self): | ||
return {"success": True} | ||
|
||
def create_query_connection(self, query): | ||
return {"success": True, "search_id": query} | ||
|
||
def create_status_connection(self, search_id): | ||
return {"success": True, "status": "COMPLETED", "progress": 100} | ||
|
||
def create_results_connection(self, search_id, offset, length): | ||
# search_id is the pattern | ||
observations = [] | ||
return_obj = dict() | ||
|
||
bundle_url = self.connection.get('host') | ||
auth = self.configuration.get('auth') | ||
|
||
if auth is not None: | ||
response = requests.get(bundle_url, auth=(auth.get('username'), auth.get('password'))) | ||
else: | ||
response = requests.get(bundle_url) | ||
|
||
response_code = response.status_code | ||
|
||
if response_code != 200: | ||
response_txt = response.raise_for_status() | ||
if ErrorResponder.is_plain_string(response_txt): | ||
ErrorResponder.fill_error(return_obj, message=response_txt) | ||
elif ErrorResponder.is_json_string(response_txt): | ||
response_json = json.loads(response_txt) | ||
ErrorResponder.fill_error(return_obj, response_json, ['reason']) | ||
else: | ||
raise UnexpectedResponseException | ||
else: | ||
bundle = response.json() | ||
|
||
if "validate" in self.configuration and self.configuration["validate"] is True: | ||
results = validate_instance(bundle) | ||
|
||
if results.is_valid is not True: | ||
return {"success": False, "message": "Invalid STIX received: " + json.dumps(results)} | ||
|
||
for obj in bundle["objects"]: | ||
if obj["type"] == "observed-data": | ||
observations.append(obj) | ||
|
||
# Pattern match | ||
results = self.match(search_id, observations, False) | ||
|
||
if len(results) != 0: | ||
return_obj['success'] = True | ||
return_obj['data'] = results[int(offset):int(offset + length)] | ||
else: | ||
return_obj['success'] = True | ||
return_obj['data'] = [] | ||
|
||
return return_obj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters