def generate_detection_events(): """ Since write_json() wants to take a generator and fetch_detection_events() returns tuples, where the detection events are an array in the tuple, we use this auxilary function to allow us to stream the events to write_json() """ event_filters = [ c42api.create_filter_by_utc_datetime(args.min_date, args.max_date) ] * len(device_guids) guids_and_filters = zip(device_guids, event_filters) for _, _, detection_events in c42api.fetch_detection_events( server, guids_and_filters): for event in detection_events: yield event
def fetch_detection_events_test(): """ Test we fetch detection events in an expected way """ cursor_string = generate_cursor() device_guids = [1, 2, 3] event_filters = ['word'] * 3 guids_and_filters = zip(device_guids, event_filters) expected_results = {} for device_guid in device_guids: expected_results[str(device_guid)] = [ 'word', generate_detection_events(random.randint(1, 20)) ] event_filter = c42api.create_filter_by_cursor(cursor_string) def mock_fetch_detection_events_for_device(server, device_guid, event_filter): """ Mock Func """ return expected_results[str(device_guid)][0], expected_results[str( device_guid)][1] def mock_fetch_security_plan(server, device_guid): """ Mock Func """ return {'planUid': 12312123} def mock_storage_servers(authority, plan_uids=None, device_guid=None): """ Mock Func """ return basic_server(), 1232 c42api.security_event_restore._fetch_detection_events_for_device = mock_fetch_detection_events_for_device c42api.security_event_restore._fetch_security_plan = mock_fetch_security_plan c42api.security_event_restore.fetch_storage.storage_servers = mock_storage_servers for device_guid, cursor, detection_events in c42api.fetch_detection_events( basic_server(), guids_and_filters): assert (device_guid in device_guids and cursor == expected_results[str(device_guid)][0] and detection_events == expected_results[str(device_guid)][1])
def fetch_detection_events_test(): """ Test we fetch detection events in an expected way """ cursor_string = generate_cursor() device_guids = [1, 2, 3] event_filters = ['word'] * 3 guids_and_filters = zip(device_guids, event_filters) expected_results = {} for device_guid in device_guids: expected_results[str(device_guid)] = [ 'word', generate_detection_events(random.randint(1, 20)) ] event_filter = c42api.create_filter_by_cursor(cursor_string) def mock_fetch_detection_events_for_device(server, device_guid, event_filter): """ Mock Func """ return expected_results[str(device_guid)][0], expected_results[str(device_guid)][1] def mock_fetch_security_plan(server, device_guid): """ Mock Func """ return {'planUid':12312123} def mock_storage_servers(authority, plan_uids=None, device_guid=None): """ Mock Func """ return basic_server(), 1232 c42api.security_event_restore._fetch_detection_events_for_device = mock_fetch_detection_events_for_device c42api.security_event_restore._fetch_security_plan = mock_fetch_security_plan c42api.security_event_restore.fetch_storage.storage_servers = mock_storage_servers for device_guid, cursor, detection_events in c42api.fetch_detection_events(basic_server(), guids_and_filters): assert (device_guid in device_guids and cursor == expected_results[str(device_guid)][0] and detection_events == expected_results[str(device_guid)][1])
def _run(): """ Run through Splunk. This is how the Splunk app gathers security detection events from the Code42 server(s). For each user, we gather all events for """ server, config_dict = common.setup() events_dir = os.path.join(common.app_home(), 'events') # The file at 'minTs_file_path' holds the 'min timestamp' to be used for a particular device the next time # the script runs. This is updated IFF all pages are gathered for a particular device during a single run of the script. minTs_file_path = os.path.join(events_dir, 'security-lastRun') # The file at 'cursor path' is used to hold the 'latest cursor' for a particular plan on a page by page basis. # i.e. every time we finish retrieving a plan, we save the new 'latest cursor' to ensure that we can restart # from the correct page in the case the connection to the C42 server goes down before we retrieve all pages. cursor_path = os.path.join(events_dir, 'security-interrupted-lastCursor') if not os.path.exists(events_dir): os.makedirs(events_dir) devices = config_dict['devices'] device_guids = c42api.devices(server, devices) timestamp_dict = _try_read_timestamp(minTs_file_path) event_filters = [] for device_guid in device_guids: try: minTs = timestamp_dict[device_guid] event_filter = c42api.create_filter_by_iso_minTs_and_now(minTs) event_filters.append(event_filter) except (KeyError, TypeError): event_filter = c42api.create_filter_by_utc_datetime( datetime.utcfromtimestamp(0), datetime.utcnow()) event_filters.append(event_filter) guids_and_filters = zip(device_guids, event_filters) timestamp_dict = timestamp_dict if timestamp_dict else {} for guid, new_minTs in c42api.fetch_detection_events( server, guids_and_filters, cursor_path): if not new_minTs: continue timestamp_dict[guid] = new_minTs _write_min_timestamps(minTs_file_path, timestamp_dict)
def _run(): """ Run through Splunk """ server, config_dict = common.setup() events_dir = os.path.join(common.app_home(), 'events') cursor_path = os.path.join(events_dir, 'security-lastRun') if not os.path.exists(events_dir): os.makedirs(events_dir) devices = config_dict['devices'] device_guids = c42api.devices(server, devices) cursors_dict = _try_read_cursor(cursor_path) event_filters = [] for device_guid in device_guids: try: cursor = cursors_dict[device_guid] event_filter = c42api.create_filter_by_cursor(cursor) event_filters.append(event_filter) except (KeyError, TypeError): event_filter = c42api.create_filter_by_utc_datetime(datetime.utcfromtimestamp(0), datetime.utcnow()) event_filters.append(event_filter) guids_and_filters = zip(device_guids, event_filters) cursors_dict = cursors_dict if cursors_dict else {} for guid, cursor, detection_events in c42api.fetch_detection_events(server, guids_and_filters): if not cursor or not detection_events: continue cursors_dict[guid] = cursor c42api.write_json_splunk(sys.stdout, detection_events) _write_cursor(cursor_path, cursors_dict)