def get_file_tree(sid, **kwargs): """ Get the file hierarchy of a given Submission ID. This is an N deep recursive process but is limited to the max depth set in the system settings. Variables: sid => Submission ID to get the tree for Arguments: None Data Block: None API call example: /api/v3/submission/tree/12345678-1234-1234-1234-1234567890AB/ Result example: { # Dictionary of file blocks "1f...11": { # File SRL (sha256) "score": 923, # Score for the file "name": ["file.exe",...] # List of possible names for the file "children": {...} # Dictionary of children file blocks }, ... """ user = kwargs['user'] data = STORAGE.get_submission(sid) if data is None: return make_api_response("", "Submission ID %s does not exists." % sid, 404) if data and user and Classification.is_accessible(user['classification'], data['classification']): output = STORAGE.create_file_tree(data) return make_api_response(output) else: return make_api_response("", "You are not allowed to view the data of this submission", 403)
def get_full_results(sid, **kwargs): """ Get the full results for a given Submission ID. The difference between this and the get results API is that this one gets the actual values of the result and error keys instead of listing the keys. Variables: sid => Submission ID to get the full results for Arguments: None Data Block: None Result example: {"classification": "UNRESTRICTIED" # Access control for the submission "error_count": 0, # Number of errors in this submission "errors": [], # List of error blocks (see Get Service Error) "file_count": 4, # Number of files in this submission "files": [ # List of submitted files ["FNAME", "SRL"], ...], # Each file = List of name/srl "file_infos": { # Dictionary of fil info blocks "234...235": <<FILE_INFO>>, # File in block ...}, # Keyed by file's SRL "file_tree": { # File tree of the submission "333...7a3": { # File tree item "children": {}, # Recursive children of file tree item "name": ["file.exe",...] # List of possible names for the file "score": 0 # Score of the file },, ...}, # Keyed by file's SRL "missing_error_keys": [], # Errors that could not be fetched from the datastore "missing_result_keys": [], # Results that could not be fetched from the datastore "results": [], # List of Results Blocks (see Get Service Result) "services": { # Service Block "selected": ["mcafee"], # List of selected services "params": {}, # Service specific parameters "excluded": [] # List of excluded services }, "state": "completed", # State of the submission "submission": { # Submission Block "profile": true, # Should keep stats about execution? "description": "", # Submission description "ttl": 30, # Submission days to live "ignore_filtering": false, # Ignore filtering services? "priority": 1000, # Submission priority, higher = faster "ignore_cache": true, # Force reprocess even is result exist? "groups": ["group", ...], # List of groups with access "sid": "ab9...956", # Submission ID "submitter": "user", # Uname of the submitter "max_score": 1422, # Score of highest scoring file "ignore_tag": false }, # Send all files to all service? "times": { # Timing block "completed": "2014-...", # Completed time "submitted": "2014-..." # Submitted time } } """ max_retry = 10 def get_results(keys): out = {} res = {} retry = 0 while keys and retry < max_retry: if retry: time.sleep(2 ** (retry - 7)) res.update(STORAGE.get_results_dict(keys)) keys = [x for x in keys if x not in res] retry += 1 results = {} for k, v in res.iteritems(): file_info = data['file_infos'].get(k[:64], None) if file_info: v = format_result(user['classification'], v, file_info['classification']) if v: results[k] = v out["results"] = results out["missing_result_keys"] = keys return out def get_errors(keys): out = {} err = {} retry = 0 while keys and retry < max_retry: if retry: time.sleep(2 ** (retry - 7)) err.update(STORAGE.get_errors_dict(keys)) keys = [x for x in err_keys if x not in err] retry += 1 out["errors"] = err out["missing_error_keys"] = keys return out def get_file_infos(keys): infos = {} retry = 0 while keys and retry < max_retry: if retry: time.sleep(2 ** (retry - 7)) infos.update(STORAGE.get_files_dict(keys)) keys = [x for x in keys if x not in infos] retry += 1 return infos def recursive_flatten_tree(tree): srls = [] for key, val in tree.iteritems(): srls.extend(recursive_flatten_tree(val.get('children', {}))) if key not in srls: srls.append(key) return list(set(srls)) user = kwargs['user'] data = STORAGE.get_submission(sid) if data is None: return make_api_response("", "Submission ID %s does not exists." % sid, 404) if data and user and Classification.is_accessible(user['classification'], data['classification']): res_keys = data.get("results", []) err_keys = data.get("errors", []) data['file_tree'] = STORAGE.create_file_tree(data) data['file_infos'] = get_file_infos(recursive_flatten_tree(data['file_tree'])) data.update(get_results(res_keys)) data.update(get_errors(err_keys)) return make_api_response(data) else: return make_api_response("", "You are not allowed to view the data of this submission", 403)