#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import csv import texttable import html from core.alert import messages from core.alert import info, write from core.compatible import version_info from core.time import now from core.die import die_failure from database.db import get_logs_by_scan_unique_id from database.db import submit_report_to_db from core.utility import merge_logs_to_list def build_graph(graph_name, events): """ build a graph Args: graph_name: graph name events: list of events Returns: graph in HTML type """ info(messages("build_graph")) try: start = getattr( __import__( 'lib.graph.{0}.engine'.format( graph_name.rsplit('_graph')[0] ), fromlist=['start'] ), 'start' ) except Exception: die_failure( messages("graph_module_unavailable").format(graph_name) ) info(messages("finish_build_graph")) return start( events ) def build_texttable(events): """ value['date'], value["target"], value['module_name'], value['scan_unique_id'], value['options'], value['event'] build a text table with generated event related to the scan :param events: all events :return: array [text table, event_number] """ _table = texttable.Texttable() table_headers = [ 'date', 'target', 'module_name', 'port', 'logs' ] _table.add_rows( [ table_headers ] ) for event in events: log = merge_logs_to_list(json.loads(event["json_event"]), []) _table.add_rows( [ table_headers, [ event['date'], event['target'], event['module_name'], event['port'], "\n".join(log) if log else "Detected" ] ] ) return _table.draw().encode('utf8') + b'\n\n' + messages("nettacker_version_details").format( version_info()[0], version_info()[1], now() ).encode('utf8') + b"\n" def create_report(options, scan_unique_id): """ sort all events, create log file in HTML/TEXT/JSON and remove old logs Args: options: parsing options scan_unique_id: scan unique id Returns: True if success otherwise None """ all_scan_logs = get_logs_by_scan_unique_id(scan_unique_id) if not all_scan_logs: info(messages("no_events_for_report")) return True report_path_filename = options.report_path_filename if ( len(report_path_filename) >= 5 and report_path_filename[-5:] == '.html' ) or ( len(report_path_filename) >= 4 and report_path_filename[-4:] == '.htm' ): if options.graph_name: html_graph = build_graph(options.graph_name, all_scan_logs) else: html_graph = '' from lib.html_log import log_data html_table_content = log_data.table_title.format( html_graph, log_data.css_1, 'date', 'target', 'module_name', 'port', 'logs', 'json_event' ) index=1 for event in all_scan_logs: log = merge_logs_to_list(json.loads(event["json_event"]), []) html_table_content += log_data.table_items.format( event["date"], event["target"], event["module_name"], event["port"], "
".join(log) if log else "Detected", #event["event"], #log index, html.escape(event["json_event"]) ) index+=1 html_table_content += log_data.table_end + '
' + str(index-1) + '
' + '' + log_data.json_parse_js with open(report_path_filename, 'w', encoding='utf-8') as save: save.write(html_table_content + '\n') save.close() elif len(report_path_filename) >= 5 and report_path_filename[-5:] == '.json': with open(report_path_filename, 'w', encoding='utf-8') as save: save.write( str( json.dumps(all_scan_logs) ) + '\n' ) save.close() elif len(report_path_filename) >= 5 and report_path_filename[-4:] == '.csv': keys = all_scan_logs[0].keys() with open(report_path_filename, 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=keys) writer.writeheader() for log in all_scan_logs: dict_data = { key: value for key, value in log.items() if key in keys } writer.writerow(dict_data) csvfile.close() else: with open(report_path_filename, 'wb') as save: save.write( build_texttable(all_scan_logs) ) save.close() write(build_texttable(all_scan_logs)) submit_report_to_db( { "date": now(model=None), "scan_unique_id": scan_unique_id, "options": vars(options), } ) info(messages("file_saved").format(report_path_filename)) return True