Skip to content

Commit

Permalink
Release v1.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
TheGroundZero committed Oct 10, 2018
1 parent 7f007a6 commit d26002f
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 24 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Changelog
=========

1.4.1 - Small bugfixes and code refactoring

1.4.0 - Use Word template for report building

1.3.1 - Add charts to Word document using matplotlib. Some code clean-up and small lay-out changes in Excel.
Expand Down
8 changes: 3 additions & 5 deletions openvasreporting/libs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@

"""This file contains data structures"""

from pathlib import Path


class Config(object):
def __init__(self, input_files, output_file="openvas_report", min_level="none", filetype="xlsx",
template="openvasreporting/src/openvas-template.docx"):
template=None):
"""
:param input_files: input file path
:type input_files: list(str)
Expand Down Expand Up @@ -43,15 +41,15 @@ def __init__(self, input_files, output_file="openvas_report", min_level="none",
raise TypeError("Expected str, got '{}' instead".format(type(min_level)))
if not isinstance(filetype, str):
raise TypeError("Expected str, got '{}' instead".format(type(filetype)))
if not isinstance(template, str):
if template is not None and not isinstance(template, str):
raise TypeError("Expected str, got '{}' instead".format(type(template)))

self.input_files = input_files
self.output_file = "{}.{}".format(output_file, filetype) if output_file.split(".")[-1] != filetype \
else output_file
self.min_level = min_level
self.filetype = filetype
self.template = Path(template).resolve()
self.template = template

@staticmethod
def colors():
Expand Down
85 changes: 78 additions & 7 deletions openvasreporting/libs/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ def exporters():
"""
return {
'xlsx': export_to_excel,
'docx': export_to_word
'docx': export_to_word,
'csv': export_to_csv
}


def export_to_excel(vuln_info, template=None, output_file='openvas_report'):
def export_to_excel(vuln_info, template=None, output_file='openvas_report.xlsx'):
"""
Export vulnerabilities info in an Excel file.
Expand Down Expand Up @@ -295,7 +296,7 @@ def __row_height(text, width):
workbook.close()


def export_to_word(vuln_info, template, output_file='openvas_report'):
def export_to_word(vuln_info, template, output_file='openvas_report.docx'):
"""
Export vulnerabilities info in a Word file.
Expand All @@ -306,7 +307,7 @@ def export_to_word(vuln_info, template, output_file='openvas_report'):
:type output_file: str
:param template: Path to Docx template
:type template: PosixPath, str
:type template: str
:raises: TypeError
"""
Expand All @@ -316,7 +317,6 @@ def export_to_word(vuln_info, template, output_file='openvas_report'):
import tempfile
import os

from pathlib import PosixPath
from docx import Document
from docx.oxml.shared import qn, OxmlElement
from docx.oxml.ns import nsdecls
Expand All @@ -334,8 +334,11 @@ def export_to_word(vuln_info, template, output_file='openvas_report'):
else:
if not output_file:
raise ValueError("output_file must have a valid name.")
if not isinstance(template, (str, PosixPath)):
raise TypeError("Expected str or PosixPath, got '{}' instead".format(type(template)))
if template is not None:
if not isinstance(template, str):
raise TypeError("Expected str, got '{}' instead".format(type(template)))
else:
template = 'openvasreporting/src/openvas-template.docx'

# TODO Move to function to de-duplicate this
vuln_info.sort(key=lambda key: key.cvss, reverse=True)
Expand Down Expand Up @@ -581,3 +584,71 @@ def __label_bars(barcontainer):
cells[2].text = "No port info"

document.save(output_file)


def export_to_csv(vuln_info, template=None, output_file='openvas_report.csv'):
"""
Export vulnerabilities info in a Comma Separated Values (csv) file
:param vuln_info: Vulnerability list info
:type vuln_info: list(Vulnerability)
:param template: Not supported in csv-output
:type template: NoneType
:param output_file: Filename of the csv file
:type output_file: str
:raises: TypeError, NotImplementedError
"""

import csv

if not isinstance(vuln_info, list):
raise TypeError("Expected list, got '{}' instead".format(type(vuln_info)))
else:
for x in vuln_info:
if not isinstance(x, Vulnerability):
raise TypeError("Expected Vulnerability, got '{}' instead".format(type(x)))
if not isinstance(output_file, str):
raise TypeError("Expected str, got '{}' instead".format(type(output_file)))
else:
if not output_file:
raise ValueError("output_file must have a valid name.")
if template is not None:
raise NotImplementedError("Use of template is not supported in CSV-output.")

# TODO Move to function to de-duplicate this
vuln_info.sort(key=lambda key: key.cvss, reverse=True)

with open(output_file, 'w') as csvfile:
fieldnames = ['hostname', 'ip', 'port', 'protocol',
'vulnerability', 'cvss', 'threat', 'family',
'description', 'detection', 'insight', 'impact', 'affected', 'solution', 'solution_type',
'vuln_id', 'cve', 'references']
writer = csv.DictWriter(csvfile, dialect='excel', fieldnames=fieldnames)
writer.writeheader()

for vuln in vuln_info:
for (host, port) in vuln.hosts:
rowdata = {
'hostname': host.host_name,
'ip': host.ip,
'port': port.number,
'protocol': port.protocol,
'vulnerability': vuln.name,
'cvss': vuln.cvss,
'threat': vuln.level,
'family': vuln.family,
'description': vuln.description,
'detection': vuln.detect,
'insight': vuln.insight,
'impact': vuln.impact,
'affected': vuln.affected,
'solution': vuln.solution,
'solution_type': vuln.solution_type,
'vuln_id': vuln.vuln_id,
'cve': ' - '.join(vuln.cves),
'references': ' - '.join(vuln.references)
}
writer.writerow(rowdata)
50 changes: 39 additions & 11 deletions openvasreporting/openvasreporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,59 @@ def main():
parser.add_argument("-i", "--input", nargs="*", dest="input_files", help="OpenVAS XML reports", required=True)
parser.add_argument("-o", "--output", dest="output_file", help="Output file, no extension", required=False,
default="openvas_report")
parser.add_argument("-l", "--level", dest="min_level", help="Minimal level (c, h, m, l, n)", required=False,
default="n")
parser.add_argument("-l", "--level", dest="min_lvl", help="Minimal level (c, h, m, l, n)", required=False,
default="none")
parser.add_argument("-f", "--format", dest="filetype", help="Output format (xlsx)", required=False, default="xlsx")
parser.add_argument("-t", "--template", dest="template", help="Template file for docx export", required=False)

args = parser.parse_args()

min_lvl = args.min_level.lower()[0]
config = create_config(args.input_files, args.output_file, args.min_lvl, args.filetype, args.template)

convert(config)


def create_config(input_files, output_file="openvas_report", min_lvl="none", filetype="xlsx", template=None):
"""
Create config file to be used by converter.
:param input_files: input XML file(s) to be converted
:type input_files: str
:param output_file: output filename for report
:type output_file: str
:param min_lvl: minimal threat level to be included in the report
:type min_lvl: str
:param filetype: filetype of the output file
:type filetype: str
:param template: template to be used in case of export to docx filetype
:type template: str
:raises: ValueError
:return: config file to be passed to converter
:rtype: Config
"""

min_lvl = min_lvl.lower()[0]

if min_lvl in Config.levels().keys():
min_lvl = Config.levels()[min_lvl]
else:
raise ValueError("Invalid value for level parameter, \
must be one of: c[ritical], h[igh], m[edium], l[low], n[one]")
must be one of: c[ritical], h[igh], m[edium], l[low], n[one]")

if args.filetype not in exporters().keys():
raise ValueError("Filetype not supported, got {}, expecting one of {}".format(args.filetype,
if filetype not in exporters().keys():
raise ValueError("Filetype not supported, got {}, expecting one of {}".format(filetype,
exporters().keys()))

if args.template is not None:
config = Config(args.input_files, args.output_file, min_lvl, args.filetype, args.template)
if template is not None:
return Config(input_files, output_file, min_lvl, filetype, template)
else:
config = Config(args.input_files, args.output_file, min_lvl, args.filetype)

convert(config)
return Config(input_files, output_file, min_lvl, filetype)


def convert(config):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
setup(
name='OpenVAS Reporting',
description='A tool to convert OpenVAS XML into reports.',
version='1.4.0',
version='1.4.1',
long_description=long_description,
long_description_content_type='text/markdown',
author='TheGroundZero (@DezeStijn)',
Expand Down

0 comments on commit d26002f

Please sign in to comment.