async def get_nodes(filter_node=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, filters={}, q=''): # set default value to 'filter_type' parameter filter_type = filters['type'] if 'type' in filters else 'all' if q: # if exists q parameter, apply limit and offset after filtering by q arguments = { 'filter_node': filter_node, 'offset': 0, 'limit': common.database_limit, 'sort': sort, 'search': search, 'select': select, 'filter_type': filter_type } else: arguments = { 'filter_node': filter_node, 'offset': offset, 'limit': limit, 'sort': sort, 'search': search, 'select': select, 'filter_type': filter_type } result = json.loads(await local_client.execute( command=b'get_nodes', data=json.dumps(arguments).encode(), wait_for_complete=False)) if 'error' in result and result['error'] > 0: raise Exception(result['message']) if q: result['items'] = filter_array_by_query(q, result['items']) # get totalItems after applying q filter result['totalItems'] = len(result['items']) # apply offset and limit filters result['items'] = result['items'][offset:offset + limit] return result
def get_decoders(offset=0, limit=common.database_limit, sort=None, search=None, filters={}, q=''): """ Gets a list of available decoders. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param search: Looks for items with the specified string. :param filters: Defines field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}. This filter is used for filtering by 'status', 'path', 'file', 'name' and 'parents'. :param q: Defines query to filter. :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ # set default values to parameters status = filters.get('status', None) path = filters.get('path', None) file_ = filters.get('file', None) name = filters.get('name', None) parents = filters.get('parents', None) status = Decoder.__check_status(status) all_decoders = [] for decoder_file in Decoder.get_decoders_files(status=status, limit=None)['items']: all_decoders.extend( Decoder.__load_decoders_from_file(decoder_file['file'], decoder_file['path'], decoder_file['status'])) decoders = list(all_decoders) for d in all_decoders: if path and path != d.path: decoders.remove(d) continue if file_ and file_ != d.file: decoders.remove(d) continue if name and name != d.name: decoders.remove(d) continue if parents and 'parent' in d.details: decoders.remove(d) continue if search: decoders = search_array(decoders, search['value'], search['negation']) if q: # decoders contains a list of Decoder objects, it is necessary to cast it into dictionaries decoders = filter_array_by_query( q, [decoder.to_dict() for decoder in decoders]) if sort: decoders = sort_array(decoders, sort['fields'], sort['order'], Decoder.SORT_FIELDS) else: decoders = sort_array(decoders, ['file', 'position'], 'asc') return { 'items': cut_array(decoders, offset, limit), 'totalItems': len(decoders) }
def ossec_log(months=3, offset=0, limit=common.database_limit, sort=None, search=None, filters={}, q=''): """ Gets logs from ossec.log. :param months: Returns logs of the last n months. By default is 3 months. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param search: Looks for items with the specified string. :param filters: Defines field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}. This filter is used for filtering by 'type_log' (all, error or info) or 'category' (i.e. ossec-remoted). :param q: Defines query to filter. :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ # set default values to 'type_log' and 'category' parameters type_log = filters.get('type_log', 'all') category = filters.get('category', 'all') logs = [] first_date = previous_month(months) statfs_error = "ERROR: statfs('******') produced error: No such file or directory" for line in tail(common.ossec_log, 2000): log_fields = __get_ossec_log_fields(line) if log_fields: log_date, log_category, level, description = log_fields if log_date < first_date: continue if category != 'all': if log_category: if log_category != category: continue else: continue # We transform local time (ossec.log) to UTC maintaining time integrity and log format log_line = { 'timestamp': log_date.astimezone( timezone.utc).strftime('%Y-%m-%d %H:%M:%S'), 'tag': log_category, 'level': level, 'description': description } if type_log == 'all': logs.append(log_line) elif type_log.lower() == level.lower(): if "ERROR: statfs(" in line: if statfs_error in logs: continue else: logs.append(statfs_error) else: logs.append(log_line) else: continue else: if logs and line and log_category == logs[-1][ 'tag'] and level == logs[-1]['level']: logs[-1]['description'] += "\n" + line if search: logs = search_array(logs, search['value'], search['negation']) if q: logs = filter_array_by_query(q, logs) if sort: if sort['fields']: logs = sort_array(logs, order=sort['order'], sort_by=sort['fields']) else: logs = sort_array(logs, order=sort['order'], sort_by=['timestamp']) else: logs = sort_array(logs, order='desc', sort_by=['timestamp']) return {'items': cut_array(logs, offset, limit), 'totalItems': len(logs)}
def get_rules(offset=0, limit=common.database_limit, sort=None, search=None, filters={}, q=''): """ Gets a list of rules. :param offset: First item to return. :param limit: Maximum number of items to return. :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}. :param search: Looks for items with the specified string. :param filters: Defines field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}. This filter is used for filtering by 'status', 'group', 'pci', 'gpg13', 'gdpr', 'hipaa', 'nist-800-53', 'file', 'path', 'id' and 'level'. :param q: Defines query to filter. :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)} """ # set default values to parameters status = filters.get('status', None) group = filters.get('group', None) pci = filters.get('pci', None) gpg13 = filters.get('gpg13', None) gdpr = filters.get('gdpr', None) hipaa = filters.get('hipaa', None) nist_800_53 = filters.get('nist-800-53', None) path = filters.get('path', None) file_ = filters.get('file', None) id_ = filters.get('id', None) level = filters.get('level', None) all_rules = [] if level: levels = level.split('-') if len(levels) < 0 or len(levels) > 2: raise WazuhException(1203) for rule_file in Rule.get_rules_files(status=status, limit=None)['items']: all_rules.extend( Rule.__load_rules_from_file(rule_file['file'], rule_file['path'], rule_file['status'])) rules = list(all_rules) for r in all_rules: if group and group not in r.groups: rules.remove(r) continue elif pci and pci not in r.pci: rules.remove(r) continue elif gpg13 and gpg13 not in r.gpg13: rules.remove(r) continue elif gdpr and gdpr not in r.gdpr: rules.remove(r) continue elif hipaa and hipaa not in r.hipaa: rules.remove(r) continue elif nist_800_53 and nist_800_53 not in r.nist_800_53: rules.remove(r) continue elif path and path != r.path: rules.remove(r) continue elif file_ and file_ != r.file: rules.remove(r) continue elif id_ and int(id_) != r.id: rules.remove(r) continue elif level: if len(levels) == 1: if int(levels[0]) != r.level: rules.remove(r) continue elif not (int(levels[0]) <= r.level <= int(levels[1])): rules.remove(r) continue if search: rules = search_array(rules, search['value'], search['negation']) if q: # rules contains a list of Rule objects, it is necessary to cast it into dictionaries rules = filter_array_by_query(q, [rule.to_dict() for rule in rules]) if sort: rules = sort_array(rules, sort['fields'], sort['order'], Rule.SORT_FIELDS) else: rules = sort_array(rules, ['id'], 'asc') return { 'items': cut_array(rules, offset, limit), 'totalItems': len(rules) }