1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
# Copyright (C) 2021 Greenbone Networks GmbH |
3
|
|
|
# |
4
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later |
5
|
|
|
# |
6
|
|
|
# This program is free software: you can redistribute it and/or modify |
7
|
|
|
# it under the terms of the GNU General Public License as published by |
8
|
|
|
# the Free Software Foundation, either version 3 of the License, or |
9
|
|
|
# (at your option) any later version. |
10
|
|
|
# |
11
|
|
|
# This program is distributed in the hope that it will be useful, |
12
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
13
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14
|
|
|
# GNU General Public License for more details. |
15
|
|
|
# |
16
|
|
|
# You should have received a copy of the GNU General Public License |
17
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
18
|
|
|
|
19
|
|
|
from enum import Enum |
20
|
|
|
from typing import Any, Optional, Union |
21
|
|
|
from lxml.etree import XMLSyntaxError |
22
|
|
|
|
23
|
|
|
from gvm.errors import InvalidArgument, RequiredArgument |
24
|
|
|
from gvm.utils import add_filter, to_bool |
25
|
|
|
from gvm.xml import XmlCommand |
26
|
|
|
|
27
|
|
|
|
28
|
|
|
class ReportFormatType(Enum): |
29
|
|
|
"""Enum for builtin report formats""" |
30
|
|
|
|
31
|
|
|
ANONYMOUS_XML = '5057e5cc-b825-11e4-9d0e-28d24461215b' |
32
|
|
|
ARF = '910200ca-dc05-11e1-954f-406186ea4fc5' |
33
|
|
|
CPE = '5ceff8ba-1f62-11e1-ab9f-406186ea4fc5' |
34
|
|
|
CSV_HOSTS = '9087b18c-626c-11e3-8892-406186ea4fc5"' |
35
|
|
|
CSV_RESULTS = 'c1645568-627a-11e3-a660-406186ea4fc5' |
36
|
|
|
GCR_PDF = 'dc51a40a-c022-11e9-b02d-3f7ca5bdcb11' |
37
|
|
|
GSR_HTML = 'ffa123c9-a2d2-409e-bbbb-a6c1385dbeaa' |
38
|
|
|
GSR_PDF = '35ba7077-dc85-42ef-87c9-b0eda7e903b6' |
39
|
|
|
GXCR_PDF = 'f0d348de-c022-11e9-bc4c-4bf1d5e1a8ca' |
40
|
|
|
GXR_PDF = 'ebbc7f34-8ae5-11e1-b07b-001f29eadec8' |
41
|
|
|
ITG = '77bd6c4a-1f62-11e1-abf0-406186ea4fc5' |
42
|
|
|
LATEX = 'a684c02c-b531-11e1-bdc2-406186ea4fc5' |
43
|
|
|
NBE = '9ca6fe72-1f62-11e1-9e7c-406186ea4fc5' |
44
|
|
|
PDF = 'c402cc3e-b531-11e1-9163-406186ea4fc5' |
45
|
|
|
SVG = '9e5e5deb-879e-4ecc-8be6-a71cd0875cdd' |
46
|
|
|
TXT = 'a3810a62-1f62-11e1-9219-406186ea4fc5' |
47
|
|
|
VERINICE_ISM = 'c15ad349-bd8d-457a-880a-c7056532ee15' |
48
|
|
|
VERINICE_ITG = '50c9950a-f326-11e4-800c-28d24461215b' |
49
|
|
|
XML = 'a994b278-1f62-11e1-96ac-406186ea4fc5' |
50
|
|
|
|
51
|
|
|
|
52
|
|
|
def get_report_format_id_from_string( |
53
|
|
|
report_format: Optional[str], |
54
|
|
|
) -> Optional[ReportFormatType]: |
55
|
|
|
"""Convert an report format name into a ReportFormatType instance""" |
56
|
|
|
if not report_format: |
57
|
|
|
return None |
58
|
|
|
|
59
|
|
|
try: |
60
|
|
|
return ReportFormatType[report_format.replace(' ', '_').upper()] |
61
|
|
|
except KeyError: |
62
|
|
|
raise InvalidArgument( |
63
|
|
|
argument='report_format', |
64
|
|
|
function=get_report_format_id_from_string.__name__, |
65
|
|
|
) from KeyError |
66
|
|
|
|
67
|
|
|
|
68
|
|
|
class ReportFormatsMixin: |
69
|
|
|
def clone_report_format( |
70
|
|
|
self, report_format_id: [Union[str, ReportFormatType]] |
71
|
|
|
) -> Any: |
72
|
|
|
"""Clone a report format from an existing one |
73
|
|
|
|
74
|
|
|
Arguments: |
75
|
|
|
report_format_id: UUID of the existing report format |
76
|
|
|
or ReportFormatType (enum) |
77
|
|
|
|
78
|
|
|
Returns: |
79
|
|
|
The response. See :py:meth:`send_command` for details. |
80
|
|
|
""" |
81
|
|
|
if not report_format_id: |
82
|
|
|
raise RequiredArgument( |
83
|
|
|
function=self.clone_report_format.__name__, |
84
|
|
|
argument='report_format_id', |
85
|
|
|
) |
86
|
|
|
|
87
|
|
|
cmd = XmlCommand("create_report_format") |
88
|
|
|
|
89
|
|
|
if isinstance(report_format_id, ReportFormatType): |
90
|
|
|
report_format_id = report_format_id.value |
91
|
|
|
|
92
|
|
|
cmd.add_element("copy", report_format_id) |
93
|
|
|
return self._send_xml_command(cmd) |
94
|
|
|
|
95
|
|
|
def delete_report_format( |
96
|
|
|
self, |
97
|
|
|
report_format_id: Optional[Union[str, ReportFormatType]] = None, |
98
|
|
|
*, |
99
|
|
|
ultimate: Optional[bool] = False, |
100
|
|
|
) -> Any: |
101
|
|
|
"""Deletes an existing report format |
102
|
|
|
|
103
|
|
|
Arguments: |
104
|
|
|
report_format_id: UUID of the report format to be deleted. |
105
|
|
|
or ReportFormatType (enum) |
106
|
|
|
ultimate: Whether to remove entirely, or to the trashcan. |
107
|
|
|
""" |
108
|
|
|
if not report_format_id: |
109
|
|
|
raise RequiredArgument( |
110
|
|
|
function=self.delete_report_format.__name__, |
111
|
|
|
argument='report_format_id', |
112
|
|
|
) |
113
|
|
|
|
114
|
|
|
cmd = XmlCommand("delete_report_format") |
115
|
|
|
|
116
|
|
|
if isinstance(report_format_id, ReportFormatType): |
117
|
|
|
report_format_id = report_format_id.value |
118
|
|
|
|
119
|
|
|
cmd.set_attribute("report_format_id", report_format_id) |
120
|
|
|
|
121
|
|
|
cmd.set_attribute("ultimate", to_bool(ultimate)) |
122
|
|
|
|
123
|
|
|
return self._send_xml_command(cmd) |
124
|
|
|
|
125
|
|
View Code Duplication |
def get_report_formats( |
|
|
|
|
126
|
|
|
self, |
127
|
|
|
*, |
128
|
|
|
filter_string: Optional[str] = None, |
129
|
|
|
filter_id: Optional[str] = None, |
130
|
|
|
trash: Optional[bool] = None, |
131
|
|
|
alerts: Optional[bool] = None, |
132
|
|
|
params: Optional[bool] = None, |
133
|
|
|
details: Optional[bool] = None, |
134
|
|
|
) -> Any: |
135
|
|
|
"""Request a list of report formats |
136
|
|
|
|
137
|
|
|
Arguments: |
138
|
|
|
filter_string: Filter term to use for the query |
139
|
|
|
filter_id: UUID of an existing filter to use for the query |
140
|
|
|
trash: Whether to get the trashcan report formats instead |
141
|
|
|
alerts: Whether to include alerts that use the report format |
142
|
|
|
params: Whether to include report format parameters |
143
|
|
|
details: Include report format file, signature and parameters |
144
|
|
|
|
145
|
|
|
Returns: |
146
|
|
|
The response. See :py:meth:`send_command` for details. |
147
|
|
|
""" |
148
|
|
|
cmd = XmlCommand("get_report_formats") |
149
|
|
|
|
150
|
|
|
add_filter(cmd, filter_string, filter_id) |
151
|
|
|
|
152
|
|
|
if details is not None: |
153
|
|
|
cmd.set_attribute("details", to_bool(details)) |
154
|
|
|
|
155
|
|
|
if alerts is not None: |
156
|
|
|
cmd.set_attribute("alerts", to_bool(alerts)) |
157
|
|
|
|
158
|
|
|
if params is not None: |
159
|
|
|
cmd.set_attribute("params", to_bool(params)) |
160
|
|
|
|
161
|
|
|
if trash is not None: |
162
|
|
|
cmd.set_attribute("trash", to_bool(trash)) |
163
|
|
|
|
164
|
|
|
return self._send_xml_command(cmd) |
165
|
|
|
|
166
|
|
View Code Duplication |
def get_report_format( |
|
|
|
|
167
|
|
|
self, report_format_id: Union[str, ReportFormatType] |
168
|
|
|
) -> Any: |
169
|
|
|
"""Request a single report format |
170
|
|
|
|
171
|
|
|
Arguments: |
172
|
|
|
report_format_id: UUID of an existing report format |
173
|
|
|
or ReportFormatType (enum) |
174
|
|
|
Returns: |
175
|
|
|
The response. See :py:meth:`send_command` for details. |
176
|
|
|
""" |
177
|
|
|
cmd = XmlCommand("get_report_formats") |
178
|
|
|
if not report_format_id: |
179
|
|
|
raise RequiredArgument( |
180
|
|
|
function=self.get_report_format.__name__, |
181
|
|
|
argument='report_format_id', |
182
|
|
|
) |
183
|
|
|
|
184
|
|
|
if isinstance(report_format_id, ReportFormatType): |
185
|
|
|
report_format_id = report_format_id.value |
186
|
|
|
|
187
|
|
|
cmd.set_attribute("report_format_id", report_format_id) |
188
|
|
|
|
189
|
|
|
# for single entity always request all details |
190
|
|
|
cmd.set_attribute("details", "1") |
191
|
|
|
return self._send_xml_command(cmd) |
192
|
|
|
|
193
|
|
|
def import_report_format(self, report_format: str) -> Any: |
194
|
|
|
"""Import a report format from XML |
195
|
|
|
|
196
|
|
|
Arguments: |
197
|
|
|
report_format: Report format XML as string to import. This XML must |
198
|
|
|
contain a :code:`<get_report_formats_response>` root element. |
199
|
|
|
|
200
|
|
|
Returns: |
201
|
|
|
The response. See :py:meth:`send_command` for details. |
202
|
|
|
""" |
203
|
|
|
if not report_format: |
204
|
|
|
raise RequiredArgument( |
205
|
|
|
function=self.import_report_format.__name__, |
206
|
|
|
argument='report_format', |
207
|
|
|
) |
208
|
|
|
|
209
|
|
|
cmd = XmlCommand("create_report_format") |
210
|
|
|
|
211
|
|
|
try: |
212
|
|
|
cmd.append_xml_str(report_format) |
213
|
|
|
except XMLSyntaxError as e: |
214
|
|
|
raise InvalidArgument( |
215
|
|
|
function=self.import_report_format.__name__, |
216
|
|
|
argument='report_format', |
217
|
|
|
) from e |
218
|
|
|
|
219
|
|
|
return self._send_xml_command(cmd) |
220
|
|
|
|
221
|
|
|
def modify_report_format( |
222
|
|
|
self, |
223
|
|
|
report_format_id: Optional[Union[str, ReportFormatType]] = None, |
224
|
|
|
*, |
225
|
|
|
active: Optional[bool] = None, |
226
|
|
|
name: Optional[str] = None, |
227
|
|
|
summary: Optional[str] = None, |
228
|
|
|
param_name: Optional[str] = None, |
229
|
|
|
param_value: Optional[str] = None, |
230
|
|
|
) -> Any: |
231
|
|
|
"""Modifies an existing report format. |
232
|
|
|
|
233
|
|
|
Arguments: |
234
|
|
|
report_format_id: UUID of report format to modify |
235
|
|
|
or ReportFormatType (enum) |
236
|
|
|
active: Whether the report format is active. |
237
|
|
|
name: The name of the report format. |
238
|
|
|
summary: A summary of the report format. |
239
|
|
|
param_name: The name of the param. |
240
|
|
|
param_value: The value of the param. |
241
|
|
|
|
242
|
|
|
Returns: |
243
|
|
|
The response. See :py:meth:`send_command` for details. |
244
|
|
|
""" |
245
|
|
|
if not report_format_id: |
246
|
|
|
raise RequiredArgument( |
247
|
|
|
function=self.modify_report_format.__name__, |
248
|
|
|
argument='report_format_id ', |
249
|
|
|
) |
250
|
|
|
|
251
|
|
|
cmd = XmlCommand("modify_report_format") |
252
|
|
|
|
253
|
|
|
if isinstance(report_format_id, ReportFormatType): |
254
|
|
|
report_format_id = report_format_id.value |
255
|
|
|
|
256
|
|
|
cmd.set_attribute("report_format_id", report_format_id) |
257
|
|
|
|
258
|
|
|
if active is not None: |
259
|
|
|
cmd.add_element("active", to_bool(active)) |
260
|
|
|
|
261
|
|
|
if name: |
262
|
|
|
cmd.add_element("name", name) |
263
|
|
|
|
264
|
|
|
if summary: |
265
|
|
|
cmd.add_element("summary", summary) |
266
|
|
|
|
267
|
|
|
if param_name: |
268
|
|
|
_xmlparam = cmd.add_element("param") |
269
|
|
|
_xmlparam.add_element("name", param_name) |
270
|
|
|
|
271
|
|
|
if param_value is not None: |
272
|
|
|
_xmlparam.add_element("value", param_value) |
273
|
|
|
|
274
|
|
|
return self._send_xml_command(cmd) |
275
|
|
|
|
276
|
|
View Code Duplication |
def verify_report_format( |
|
|
|
|
277
|
|
|
self, report_format_id: Union[str, ReportFormatType] |
278
|
|
|
) -> Any: |
279
|
|
|
"""Verify an existing report format |
280
|
|
|
|
281
|
|
|
Verifies the trust level of an existing report format. It will be |
282
|
|
|
checked whether the signature of the report format currently matches the |
283
|
|
|
report format. This includes the script and files used to generate |
284
|
|
|
reports of this format. It is *not* verified if the report format works |
285
|
|
|
as expected by the user. |
286
|
|
|
|
287
|
|
|
Arguments: |
288
|
|
|
report_format_id: UUID of the report format to be verified |
289
|
|
|
or ReportFormatType (enum) |
290
|
|
|
|
291
|
|
|
Returns: |
292
|
|
|
The response. See :py:meth:`send_command` for details. |
293
|
|
|
""" |
294
|
|
|
if not report_format_id: |
295
|
|
|
raise RequiredArgument( |
296
|
|
|
function=self.verify_report_format.__name__, |
297
|
|
|
argument='report_format_id', |
298
|
|
|
) |
299
|
|
|
|
300
|
|
|
cmd = XmlCommand("verify_report_format") |
301
|
|
|
|
302
|
|
|
if isinstance(report_format_id, ReportFormatType): |
303
|
|
|
report_format_id = report_format_id.value |
304
|
|
|
|
305
|
|
|
cmd.set_attribute("report_format_id", report_format_id) |
306
|
|
|
|
307
|
|
|
return self._send_xml_command(cmd) |
308
|
|
|
|