Passed
Pull Request — master (#29)
by Juan José
05:08 queued 02:48
created

gvm.protocols.gmpv7.Gmp.modify_alert()   C

Complexity

Conditions 11

Size

Total Lines 58
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 30
nop 11
dl 0
loc 58
rs 5.4
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gvm.protocols.gmpv7.Gmp.modify_alert() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# -*- coding: utf-8 -*-
0 ignored issues
show
coding-style introduced by
Too many lines in module (1910/1000)
Loading history...
2
# Copyright (C) 2018 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
Module for communication with gvmd in Greenbone Management Protocol version 7
20
"""
21
import logging
22
23
from lxml import etree
24
25
from gvm.errors import InvalidArgument, RequiredArgument
26
from gvm.utils import get_version_string
27
from gvm.xml import _GmpCommandFactory as GmpCommandFactory, XmlCommand
28
29
from .base import GvmProtocol
30
31
logger = logging.getLogger(__name__)
32
33
PROTOCOL_VERSION = (7,)
34
35
FILTER_TYPES = [
36
    'agent',
37
    'alert',
38
    'asset',
39
    'config',
40
    'credential',
41
    'filter',
42
    'group',
43
    'note',
44
    'override',
45
    'permission',
46
    'port_list',
47
    'report',
48
    'report_format',
49
    'result',
50
    'role',
51
    'schedule',
52
    'secinfo',
53
    'tag',
54
    'target',
55
    'task',
56
    'user',
57
]
58
59
TIME_UNITS = [
60
    'second',
61
    'minute',
62
    'hour',
63
    'day',
64
    'week',
65
    'month',
66
    'year',
67
    'decade',
68
]
69
70
71
def _check_command_status(xml):
72
    """Check gmp response
73
74
    Look into the gmp response and check for the status in the root element
75
76
    Arguments:
77
        xml {string} -- XML-Source
78
79
    Returns:
80
        bool -- True if valid, otherwise False
81
    """
82
83
    if xml is 0 or xml is None:
84
        logger.error('XML Command is empty')
85
        return False
86
87
    try:
88
        parser = etree.XMLParser(encoding='utf-8', recover=True)
89
90
        root = etree.XML(xml, parser=parser)
91
        status = root.attrib['status']
92
        return status is not None and status[0] == '2'
93
94
    except etree.Error as e:
95
        logger.error('etree.XML(xml): %s', e)
96
        return False
97
98
99
class Gmp(GvmProtocol):
0 ignored issues
show
best-practice introduced by
Too many public methods (112/30)
Loading history...
100
    """Python interface for Greenbone Management Protocol
101
102
    This class implements the `Greenbone Management Protocol version 7`_
103
104
    Attributes:
105
        connection (:class:`gvm.connections.GvmConnection`): Connection to use
106
            to talk with the gvmd daemon. See :mod:`gvm.connections` for
107
            possible connection types.
108
        transform (`callable`_, optional): Optional transform callable to
109
            convert response data. After each request the callable gets passed
110
            the plain response data which can be used to check the data and/or
111
            conversion into different representaitions like a xml dom.
112
113
            See :mod:`gvm.transforms` for existing transforms.
114
115
    .. _Greenbone Management Protocol version 7:
116
        https://docs.greenbone.net/API/GMP/gmp-7.0.html
117
    .. _callable:
118
        https://docs.python.org/3.6/library/functions.html#callable
119
    """
120
121
    def __init__(self, connection, transform=None):
122
        super().__init__(connection, transform)
123
124
        # Is authenticated on gvmd
125
        self._authenticated = False
126
127
        # GMP Message Creator
128
        self._generator = GmpCommandFactory()
129
130
    @staticmethod
131
    def get_protocol_version():
132
        """Allow to determine the Greenbone Management Protocol version.
133
134
            Returns:
135
                str: Implemented version of the Greenbone Management Protocol
136
        """
137
        return get_version_string(PROTOCOL_VERSION)
138
139
    def is_authenticated(self):
140
        """Checks if the user is authenticated
141
142
        If the user is authenticated privilged GMP commands like get_tasks
143
        may be send to gvmd.
144
145
        Returns:
146
            bool: True if an authenticated connection to gvmd has been
147
            established.
148
        """
149
        return self._authenticated
150
151
    def authenticate(self, username, password):
152
        """Authenticate to gvmd.
153
154
        The generated authenticate command will be send to server.
155
        Afterwards the response is read, transformed and returned.
156
157
        Arguments:
158
            username (str): Username
159
            password (str): Password
160
161
        Returns:
162
            any, str by default: Transformed response from server.
163
        """
164
        cmd = XmlCommand('authenticate')
165
166
        if not username:
167
            raise RequiredArgument('authenticate requires username')
168
169
        if not password:
170
            raise RequiredArgument('authenticate requires password')
171
172
        credentials = cmd.add_element('credentials')
173
        credentials.add_element('username', username)
174
        credentials.add_element('password', password)
175
176
        self._send(cmd.to_string())
177
        response = self._read()
178
179
        if _check_command_status(response):
180
            self._authenticated = True
181
182
        return self._transform(response)
183
184
    def create_agent(self, installer, signature, name, comment=None, copy=None,
185
                     howto_install=None, howto_use=None):
186
        """Create a new agent
187
188
        Arguments:
189
            installer (str): A base64 encoded file that installs the agent on a
190
                target machine
191
            signature: (str): A detached OpenPGP signature of the installer
192
            name (str): A name for the agent
193
            comment (str, optional): A comment for the agent
194
            copy (str, optional): UUID of an existing agent to clone from
195
            howto_install (str, optional): A file that describes how to install
196
                the agent
197
            howto_use (str, optional): A file that describes how to use the
198
                agent
199
200
        Returns:
201
            The response. See :py:meth:`send_command` for details.
202
        """
203
        if not name:
204
            raise RequiredArgument('create_agent requires name argument')
205
206
        if not installer:
207
            raise RequiredArgument('create_agent requires installer argument')
208
209
        if not signature:
210
            raise RequiredArgument('create_agent requires signature argument')
211
212
        cmd = XmlCommand('create_agent')
213
        cmd.add_element('installer', installer)
214
        cmd.add_element('signature', signature)
215
        cmd.add_element('name', name)
216
217
        if comment:
218
            cmd.add_element('comment', comment)
219
220
        if copy:
221
            cmd.add_element('copy', copy)
222
223
        if howto_install:
224
            cmd.add_element('howto_install', howto_install)
225
226
        if howto_use:
227
            cmd.add_element('howto_use', howto_use)
228
229
        return self._send_xml_command(cmd)
230
231
    def create_alert(self, name, condition, event, method, method_data=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (19/15).
Loading history...
232
                     event_data=None, condition_data=None, filter_id=None,
233
                     copy=None, comment=None):
234
        """Create a new alert
235
236
        Arguments:
237
            name (str): Name of the new Alert
238
            condition (str): The condition that must be satisfied for the alert
239
                to occur.
240
            event (str): The event that must happen for the alert to occur
241
            method (str): The method by which the user is alerted
242
            condition_data (dict, optional): Data that defines the condition
243
            event_data (dict, optional): Data that defines the event
244
            method_data (dict, optional): Data that defines the method
245
            filter_id (str, optional): Filter to apply when executing alert
246
            copy (str, optional): UUID of the alert to clone from
247
            comment (str, optional): Comment for the alert
248
249
        Returns:
250
            The response. See :py:meth:`send_command` for details.
251
        """
252
        if not name:
253
            raise RequiredArgument('create_alert requires name argument')
254
255
        if condition is None or len(condition) == 0:
256
            raise RequiredArgument('create_alert requires condition argument')
257
258
        if event is None or len(event) == 0:
259
            raise RequiredArgument('create_alert requires event argument')
260
261
        cmd = XmlCommand('create_alert')
262
        cmd.add_element('name', name)
263
264
        conditions = cmd.add_element('condition', condition)
265
266
        if not condition_data is None:
267
            for value, key in condition_data.items():
268
                _data = conditions.add_element('data', value)
269
                _data.add_element('name', key)
270
271
        events = cmd.add_element('event', event)
272
273
        if not event_data is None:
274
            for value, key in event_data.items():
275
                _data = events.add_element('data', value)
276
                _data.add_element('name', key)
277
278
        methods = cmd.add_element('method', method)
279
280
        if not method_data is None:
281
            for value, key in method_data.items():
282
                _data = methods.add_element('data', value)
283
                _data.add_element('name', key)
284
285
        if filter_id:
286
            cmd.add_element('filter', attrs={'id': filter_id})
287
288
        if copy:
289
            cmd.add_element('copy', copy)
290
291
        if comment:
292
            cmd.add_element('comment', comment)
293
294
        return self._send_xml_command(cmd)
295
296
    def create_asset(self, name, asset_type, comment=None):
297
        """Create a new asset
298
299
        Arguments:
300
            name (str): Name for the new asset
301
            asset_type (str): Either 'os' or 'host'
302
            comment (str, optional): Comment for the new asset
303
304
        Returns:
305
            The response. See :py:meth:`send_command` for details.
306
        """
307
        if asset_type not in ('host', 'os'):
308
            raise InvalidArgument(
309
                'create_asset requires asset_type to be either host or os')
310
311
        if not name:
312
            raise RequiredArgument('create_asset requires name argument')
313
314
        cmd = XmlCommand('create_asset')
315
        asset = cmd.add_element('asset')
316
        asset.add_element('type', asset_type)
317
        asset.add_element('name', name)
318
319
        if comment:
320
            asset.add_element('comment', comment)
321
322
        return self._send_xml_command(cmd)
323
324
    def create_config(self, name, copy):
325
        """Create a new scan config from an existing one
326
327
        Arguments:
328
            name (str): Name of the new scan config
329
            copy (str): UUID of the existing scan config
330
331
        Returns:
332
            The response. See :py:meth:`send_command` for details.
333
        """
334
        if not name:
335
            raise RequiredArgument('create_config requires name argument')
336
337
        if not copy:
338
            raise RequiredArgument('create_config requires copy argument')
339
340
        cmd = XmlCommand('create_config')
341
        cmd.add_element('copy', copy)
342
        cmd.add_element('name', name)
343
        return self._send_xml_command(cmd)
344
345
    def create_credential(self, name, comment=None, copy=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (19/15).
Loading history...
346
                          allow_insecure=False, certificate=None,
347
                          key_phrase=None, private_key=None, login=None,
348
                          password=None, auth_algorithm=None, community=None,
349
                          privacy_algorithm=None, privacy_password=None,
350
                          credential_type=None):
351
        """Create a new credential
352
353
        Arguments:
354
            name (str): Name of the new credential
355
            comment (str, optional): Comment for the credential
356
            copy (str, optional): UUID of credential to clone from
357
            allow_insecure (boolean, optional): Whether to allow insecure use of
358
                the credential
359
            certificate (str, optional): Certificate for the credential
360
            key_phrase (str, optional): Key passphrase for the private key
361
            private_key (str, optional): Private key to use for login
362
            login (str, optional): Username for the credential
363
            password (str, optional): Password for the credential
364
            community (str, optional): The SNMP community
365
            privacy_alogorithm (str, optional): The SNMP privacy algorithm,
366
                either aes or des.
367
            privacy_password (str, optional): The SNMP privacy password
368
            credential_type (str, optional): The credential type. One of 'cc',
369
                'snmp', 'up', 'usk'
370
371
        Returns:
372
            The response. See :py:meth:`send_command` for details.
373
        """
374
        if not name:
375
            raise RequiredArgument('create_credential requires name argument')
376
377
        cmd = XmlCommand('create_credential')
378
        cmd.add_element('name', name)
379
380
        if comment:
381
            cmd.add_element('comment', comment)
382
383
        if copy:
384
            cmd.add_element('copy', copy)
385
386
        if allow_insecure:
387
            cmd.add_element('allow_insecure', '1')
388
389
        if certificate:
390
            cmd.add_element('certificate', certificate)
391
392
        if not key_phrase is None and private_key:
393
            _xmlkey = cmd.add_element('key')
394
            _xmlkey.add_element('phrase', key_phrase)
395
            _xmlkey.add_element('private', private_key)
396
397
        if login:
398
            cmd.add_element('login', login)
399
400
        if password:
401
            cmd.add_element('password', password)
402
403
        if auth_algorithm:
404
            if auth_algorithm not in ('md5', 'sha1'):
405
                raise InvalidArgument(
406
                    'create_credential requires auth_algorithm to be either '
407
                    'md5 or sha1')
408
            cmd.add_element('auth_algorithm', auth_algorithm)
409
410
        if community:
411
            cmd.add_element('community', community)
412
413
        if privacy_algorithm and privacy_password:
414
            if privacy_algorithm not in ('aes', 'des'):
415
                raise InvalidArgument(
416
                    'create_credential requires algorithm to be either aes or '
417
                    'des')
418
            _xmlprivacy = cmd.add_element('privacy')
419
            _xmlprivacy.add_element('algorithm', privacy_algorithm)
420
            _xmlprivacy.add_element('password', privacy_password)
421
422
        if credential_type:
423
            if credential_type not in ('cc', 'snmp', 'up', 'usk'):
424
                raise InvalidArgument(
425
                    'create_credential requires type to be either cc, snmp, up '
426
                    ' or usk')
427
            cmd.add_element('type', credential_type)
428
429
        return self._send_xml_command(cmd)
430
431
    def create_filter(self, name, make_unique=False, filter_type=None,
432
                      comment=None, term=None, copy=None):
433
        """Create a new filter
434
435
        Arguments:
436
            name (str): Name of the new filter
437
            make_unique (boolean, optional):
438
            filter_type (str, optional): Filter for entity type
439
            comment (str, optional): Comment for the filter
440
            term (str, optional): Filter term e.g. 'name=foo'
441
            copy (str, optional): UUID of an existing filter
442
443
        Returns:
444
            The response. See :py:meth:`send_command` for details.
445
        """
446
        if not name:
447
            raise RequiredArgument('create_filter requires a name argument')
448
449
        cmd = XmlCommand('create_filter')
450
        _xmlname = cmd.add_element('name', name)
451
        if make_unique:
452
            _xmlname.add_element('make_unique', '1')
453
454
        if comment:
455
            cmd.add_element('comment', comment)
456
457
        # TODO: Move copy into an extra method
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
458
        if copy:
459
            cmd.add_element('copy', copy)
460
461
        if term:
462
            cmd.add_element('term', term)
463
464
        if filter_type:
465
            filter_type = filter_type.lower()
466
            if filter_type not in FILTER_TYPES:
467
                raise InvalidArgument(
468
                    'create_filter requires type to be one of {0} but '
469
                    'was {1}'.format(', '.join(FILTER_TYPES), filter_type))
470
            cmd.add_element('type', filter_type)
471
472
        return self._send_xml_command(cmd)
473
474
    def create_group(self, name, comment=None, copy=None, special=False,
475
                     users=None):
476
        """Create a new group
477
478
        Arguments:
479
            name (str): Name of the new group
480
            comment (str, optional): Comment for the group
481
            copy (str, optional): UUID of group to clone from
482
            special (boolean, optional): Create permission giving members full
483
                access to each other's entities
484
            users (list, optional): List of user names to be in the group
485
486
        Returns:
487
            The response. See :py:meth:`send_command` for details.
488
        """
489
        if not name:
490
            raise RequiredArgument('create_group requires a name argument')
491
492
        cmd = XmlCommand('create_group')
493
        cmd.add_element('name', name)
494
495
        if comment:
496
            cmd.add_element('comment', comment)
497
498
        if copy:
499
            cmd.add_element('copy', copy)
500
501
        if special:
502
            _xmlspecial = cmd.add_element('specials')
503
            _xmlspecial.add_element('full')
504
505
        if users:
506
            cmd.add_element('users', ','.join(users))
507
508
        return self._send_xml_command(cmd)
509
510
    def create_note(self, text, nvt_oid, active=None, comment=None, copy=None,
511
                    hosts=None, result_id=None, severity=None, task_id=None,
512
                    threat=None, port=None):
513
        """Create a new note
514
515
        Arguments:
516
            text (str): Text of the new note
517
            nvt_id (str): OID of the nvt to which note applies
518
            active (int, optional): Seconds note will be active. -1 on
519
                always, 0 off
520
            comment (str, optional): Comment for the note
521
            copy (str, optional): UUID of existing note to clone from
522
            hosts (list, optional): A list of hosts addresses
523
            port (str, optional): Port to which the note applies
524
            result_id (str, optional): UUID of a result to which note applies
525
            severity (decimal, optional): Severity to which note applies
526
            task_id (str, optional): UUID of task to which note applies
527
            threat (str, optional): Threat level to which note applies. Will be
528
                converted to severity
529
530
        Returns:
531
            The response. See :py:meth:`send_command` for details.
532
        """
533
        if not text:
534
            raise RequiredArgument('create_note requires a text argument')
535
536
        if not nvt_oid:
537
            raise RequiredArgument('create_note requires a nvt_oid argument')
538
539
        cmd = XmlCommand('create_note')
540
        cmd.add_element('text', text)
541
        cmd.add_element('nvt', attrs={"oid": nvt_oid})
542
543
        if not active is None:
544
            cmd.add_element('active', str(active))
545
546
        if comment:
547
            cmd.add_element('comment', comment)
548
549
        if copy:
550
            cmd.add_element('copy', copy)
551
552
        if hosts:
553
            cmd.add_element('hosts', ', '.join(hosts))
554
555
        if port:
556
            cmd.add_element('port', port)
557
558
        if result_id:
559
            cmd.add_element('result', attrs={'id': result_id})
560
561
        if severity:
562
            cmd.add_element('severity', severity)
563
564
        if task_id:
565
            cmd.add_element('task', attrs={'id': task_id})
566
567
        if threat:
568
            cmd.add_element('threat', threat)
569
570
        return self._send_xml_command(cmd)
571
572
    def create_override(self, text, nvt_oid, active=None, copy=None, hosts=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (16/15).
Loading history...
573
                        port=None, result_id=None, severity=None, comment=None,
574
                        new_severity=None, task_id=None, threat=None,
575
                        new_threat=None):
576
        """Create a new override
577
578
        Arguments:
579
            text (str): Text of the new override
580
            nvt_id (str): OID of the nvt to which override applies
581
            active (int, optional): Seconds override will be active. -1 on
582
                always, 0 off
583
            comment (str, optional): Comment for the override
584
            copy (str, optional): UUID of existing override to clone from
585
            hosts (list, optional): A list of host addresses
586
            port (str, optional): Port ot which the override applies
587
            result_id (str, optional): UUID of a result to which override
588
                applies
589
            severity (decimal, optional): Severity to which override applies
590
            new_severity (decimal, optional): New severity for result
591
            task_id (str, optional): UUID of task to which override applies
592
            threat (str, optional): Threat level to which override applies. Will
593
                be converted to severity
594
            new_threat (str, optional): New threat level for result, will be
595
                converted to a new_severity
596
597
        Returns:
598
            The response. See :py:meth:`send_command` for details.
599
        """
600
        if not text:
601
            raise RequiredArgument('create_override requires a text argument')
602
603
        if not nvt_oid:
604
            raise RequiredArgument('create_override requires a nvt_oid '
605
                                   'argument')
606
607
        cmd = XmlCommand('create_override')
608
        cmd.add_element('text', text)
609
        cmd.add_element('nvt', attrs={'oid': nvt_oid})
610
611
        if active:
612
            cmd.add_element('active', active)
613
614
        if comment:
615
            cmd.add_element('comment', comment)
616
617
        if copy:
618
            cmd.add_element('copy', copy)
619
620
        if hosts:
621
            cmd.add_element('hosts', ', '.join(hosts))
622
623
        if port:
624
            cmd.add_element('port', port)
625
626
        if result_id:
627
            cmd.add_element('result', attrs={'id': result_id})
628
629
        if severity:
630
            cmd.add_element('severity', severity)
631
632
        if new_severity:
633
            cmd.add_element('new_severity', new_severity)
634
635
        if task_id:
636
            cmd.add_element('task', attrs={'id': task_id})
637
638
        if threat:
639
            cmd.add_element('threat', threat)
640
641
        if new_threat:
642
            cmd.add_element('new_threat', new_threat)
643
644
        return self._send_xml_command(cmd)
645
646
    def create_permission(self, name, subject_id, subject_type,
647
                          resource_id=None, resource_type=None, copy=None,
648
                          comment=None):
649
        """Create a new permission
650
651
        Arguments:
652
            name (str): Name of the new permission
653
            subject_id (str): UUID of subject to whom the permission is granted
654
            subject_type (str): Type of the subject user, group or role
655
            comment (str, optional): Comment for the permission
656
            resource_id (str, optional): UUID of entity to which the permission
657
                applies
658
            resource_type (str, optional): Type of the resource. For Super
659
                permissions user, group or role
660
661
        Returns:
662
            The response. See :py:meth:`send_command` for details.
663
        """
664
        if not name:
665
            raise RequiredArgument('create_permission requires a name argument')
666
667
        if not subject_id:
668
            raise RequiredArgument(
669
                'create_permission requires a subject_id argument')
670
671
        if subject_type not in ('user', 'group', 'role'):
672
            raise InvalidArgument(
673
                'create_permission requires subject_type to be either user, '
674
                'group or role')
675
676
        cmd = XmlCommand('create_permission')
677
        cmd.add_element('name', name)
678
679
        _xmlsubject = cmd.add_element('subject', attrs={'id': subject_id})
680
        _xmlsubject.add_element('type', type)
681
682
        if comment:
683
            cmd.add_element('comment', comment)
684
685
        if copy:
686
            cmd.add_element('copy', copy)
687
688
        if resource_id and resource_type:
689
            _xmlresource = cmd.add_element('resource',
690
                                           attrs={'id': resource_id})
691
            _xmlresource.add_element('type', resource_type)
692
693
694
        return self._send_xml_command(cmd)
695
696
    def create_port_list(self, name, port_range, comment=None, copy=None):
697
        """Create a new port list
698
699
        Arguments:
700
            name (str): Name of the new port list
701
            port_range (str): Port list ranges e.g. `"T: 1-1234"` for tcp port
702
                1 - 1234
703
            comment (str, optional): Comment for the port list
704
            copy (str, optional): UUID of existing port list to clone from
705
706
        Returns:
707
            The response. See :py:meth:`send_command` for details.
708
        """
709
        if not name:
710
            raise RequiredArgument('create_port_list requires a name argument')
711
712
        if not port_range:
713
            raise RequiredArgument(
714
                'create_port_list requires a port_range argument')
715
716
        cmd = XmlCommand('create_port_list')
717
        cmd.add_element('name', name)
718
        cmd.add_element('port_range', port_range)
719
720
        if comment:
721
            cmd.add_element('comment', comment)
722
723
        if copy:
724
            cmd.add_element('copy', copy)
725
726
        return self._send_xml_command(cmd)
727
728
    def create_port_range(self, port_list_id, start, end, port_range_type,
729
                          comment=None):
730
        """Create new port range
731
732
        Arguments:
733
            port_list_id (str): UUID of the port list to which to add the range
734
            start (int): The first port in the range
735
            end (int): The last port in the range
736
            type (str): The type of the ports: TCP, UDP, ...
737
            comment (str, optional): Comment for the port range
738
739
        Returns:
740
            The response. See :py:meth:`send_command` for details.
741
        """
742
        if not port_list_id:
743
            raise RequiredArgument('create_port_range requires '
744
                                   'a port_list_id argument')
745
746
        if not port_range_type:
747
            raise RequiredArgument(
748
                'create_port_range requires a port_range_type argument')
749
750
        if not start:
751
            raise RequiredArgument(
752
                'create_port_range requires a start argument')
753
754
        if not end:
755
            raise RequiredArgument(
756
                'create_port_range requires a end argument')
757
758
        cmd = XmlCommand('create_port_range')
759
        cmd.add_element('port_list', attrs={'id': port_list_id})
760
        cmd.add_element('start', start)
761
        cmd.add_element('end', end)
762
        cmd.add_element('type', port_range_type)
763
764
        if comment:
765
            cmd.add_element('comment', comment)
766
767
        return self._send_xml_command(cmd)
768
769
    def import_report(self, report, task_id=None, task_name=None,
770
                      task_comment=None, in_assets=None):
771
        """Import a Report
772
773
        Arguments:
774
            report (str): Report XML as string to import
775
            task_id (str, optional): UUID of task to import report to
776
            task_name (str, optional): Name of task to be createed if task_id is
777
                not present. Either task_id or task_name must be passed
778
            task_comment (str, optional): Comment for task to be created if
779
                task_id is not present
780
            in_asset (boolean, optional): Whether to create or update assets
781
                using the report
782
783
        Returns:
784
            The response. See :py:meth:`send_command` for details.
785
        """
786
        if not report:
787
            raise RequiredArgument('create_report requires a report argument')
788
789
        cmd = XmlCommand('create_report')
790
791
        if task_id:
792
            cmd.add_element('task', attrs={'id': task_id})
793
        elif task_name:
794
            _xmltask = cmd.add_element('task')
795
            _xmltask.add_element('name', task_name)
796
797
            if task_comment:
798
                _xmltask.add_element('comment', task_comment)
799
        else:
800
            raise RequiredArgument(
801
                'import_report requires a task_id or task_name argument')
802
803
        if not in_assets is None:
804
            if in_assets:
805
                cmd.add_element('in_assets', '1')
806
            else:
807
                cmd.add_element('in_assets', '0')
808
        try:
809
            cmd.append_xml_str(report)
810
        except etree.XMLSyntaxError as e:
811
            raise InvalidArgument(
812
                'Invalid xml passed as report to import_report', e)
813
814
        return self._send_xml_command(cmd)
815
816
    def create_role(self, name, comment=None, copy=None, users=None):
817
        """Create a new role
818
819
        Arguments:
820
            name (str): Name of the role
821
            comment (str, optional): Comment for the role
822
            copy (str, optional): UUID of existing role to clone from
823
            users (list, optional): List of user names to add to the role
824
825
        Returns:
826
            The response. See :py:meth:`send_command` for details.
827
        """
828
829
        if not name:
830
            raise RequiredArgument('create_role requires a name argument')
831
832
        cmd = XmlCommand('create_role')
833
        cmd.add_element('name', name)
834
835
        if comment:
836
            cmd.add_element('comment', comment)
837
838
        if copy:
839
            cmd.add_element('copy', copy)
840
841
        if users:
842
            cmd.add_element('users', ",".join(users))
843
844
        return self._send_xml_command(cmd)
845
846
    def create_scanner(self, name, host, port, scanner_type, ca_pub,
847
                       credential_id, copy=None, comment=None):
848
        """Create a new scanner
849
850
        Arguments:
851
            name (str): Name of the scanner
852
            host (str): The host of the scanner
853
            port (str): The port of the scanner
854
            scanner_type (str): The type of the scanner
855
            ca_pub (str): Certificate of CA to verify scanner certificate
856
            credential_id (str): UUID of client certificate credential for the
857
                scanner
858
            copy (str, optional): UUID of existing scanner to clone from
859
            comment (str, optional): Comment for the scanner
860
861
        Returns:
862
            The response. See :py:meth:`send_command` for details.
863
        """
864
        if not name:
865
            raise RequiredArgument('create_scanner requires a name argument')
866
867
        if not host:
868
            raise RequiredArgument('create_scanner requires a host argument')
869
870
        if not port:
871
            raise RequiredArgument('create_scanner requires a port argument')
872
873
        if not type:
874
            raise RequiredArgument('create_scanner requires a scanner_type '
875
                                   'argument')
876
        if not ca_pub:
877
            raise RequiredArgument('create_scanner requires a ca_pub argument')
878
879
        if not credential_id:
880
            raise RequiredArgument('create_scanner requires a credential_id '
881
                                   'argument')
882
883
        cmd = XmlCommand('create_scanner')
884
        cmd.add_element('name', name)
885
        cmd.add_element('host', host)
886
        cmd.add_element('port', port)
887
        cmd.add_element('type', scanner_type)
888
        cmd.add_element('ca_pub', ca_pub)
889
        cmd.add_element('credential', attrs={'id': str(credential_id)})
890
891
        if comment:
892
            cmd.add_element('comment', comment)
893
894
        if copy:
895
            cmd.add_element('copy', copy)
896
897
        return self._send_xml_command(cmd)
898
899
    def create_schedule(self, name, comment=None, copy=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (19/15).
Loading history...
900
                        first_time_minute=None, first_time_hour=None,
901
                        first_time_day_of_month=None, first_time_month=None,
902
                        first_time_year=None, duration=None, duration_unit=None,
903
                        period=None, period_unit=None, timezone=None):
904
        """Create a new schedule
905
906
        Arguments:
907
            name (str): Name of the schedule
908
            copy (str, optional): UUID of existing schedule to clone from
909
            comment (str, optional): Comment for the schedule
910
            first_time_minute (int, optional): First time minute the schedule
911
                will run
912
            first_time_hour (int, optional): First time hour the schedule
913
                will run
914
            first_time_day_of_month (int, optional): First time day of month the
915
                schedule will run
916
            first_time_month (int, optional): First time month the schedule
917
                will run
918
            first_time_year (int, optional): First time year the schedule
919
                will run
920
            duration (int, optional): How long the Manager will run the
921
                scheduled task for until it gets paused if not finished yet.
922
            duration_unit (str, optional): Unit of the duration. One of second,
923
                minute, hour, day, week, month, year, decade. Required if
924
                duration is set.
925
            period (int, optional): How often the Manager will repeat the
926
                scheduled task
927
            period_unit (str, optional): Unit of the period. One of second,
928
                minute, hour, day, week, month, year, decade. Required if
929
                period is set.
930
            timezone (str, optional): The timezone the schedule will follow
931
932
        Returns:
933
            The response. See :py:meth:`send_command` for details.
934
        """
935
        if not name:
936
            raise RequiredArgument('create_schedule requires a name argument')
937
938
        cmd = XmlCommand('create_schedule')
939
        cmd.add_element('name', name)
940
941
        if comment:
942
            cmd.add_element('comment', comment)
943
944
        if copy:
945
            cmd.add_element('copy', copy)
946
947
        if first_time_minute or first_time_hour or first_time_day_of_month or \
948
            first_time_month or first_time_year:
949
950
            if not first_time_minute:
951
                raise RequiredArgument(
952
                    'Setting first_time requires first_time_minute argument')
953
            if not first_time_hour:
954
                raise RequiredArgument(
955
                    'Setting first_time requires first_time_hour argument')
956
            if not first_time_day_of_month:
957
                raise RequiredArgument(
958
                    'Setting first_time requires first_time_day_of_month '
959
                    'argument')
960
            if not first_time_month:
961
                raise RequiredArgument(
962
                    'Setting first_time requires first_time_month argument')
963
            if not first_time_year:
964
                raise RequiredArgument(
965
                    'Setting first_time requires first_time_year argument')
966
967
            _xmlftime = cmd.add_element('first_time')
968
            _xmlftime.add_element('minute', str(first_time_minute))
969
            _xmlftime.add_element('hour', str(first_time_hour))
970
            _xmlftime.add_element('day_of_month', str(first_time_day_of_month))
971
            _xmlftime.add_element('month', str(first_time_month))
972
            _xmlftime.add_element('year', str(first_time_year))
973
974
        if duration:
975
            if not duration_unit:
976
                raise RequiredArgument(
977
                    'Setting duration requires duration_unit argument')
978
979
            if not duration_unit in TIME_UNITS:
980
                raise InvalidArgument(
981
                    'duration_unit must be one of {units} but {actual} has '
982
                    'been passed'.format(
983
                        units=', '.join(TIME_UNITS), actual=duration_unit))
984
985
            _xmlduration = cmd.add_element('duration', str(duration))
986
            _xmlduration.add_element('unit', duration_unit)
987
988
        if period:
989
            if not period_unit:
990
                raise RequiredArgument(
991
                    'Setting period requires period_unit argument')
992
993
            if not period_unit in TIME_UNITS:
994
                raise InvalidArgument(
995
                    'period_unit must be one of {units} but {actual} has '
996
                    'been passed'.format(
997
                        units=', '.join(TIME_UNITS), actual=period_unit))
998
999
            _xmlperiod = cmd.add_element('period', str(period))
1000
            _xmlperiod.add_element('unit', period_unit)
1001
1002
        if timezone:
1003
            cmd.add_element('timezone', timezone)
1004
1005
        return self._send_xml_command(cmd)
1006
1007
    def create_tag(self, name, resource_id, resource_type, copy=None,
1008
                   value=None, comment=None, active=None):
1009
        """Create a new tag
1010
1011
        Arguments:
1012
            name (str): Name of the tag. A full tag name consisting of namespace
1013
                and predicate e.g. `foo:bar`.
1014
            resource_id (str): ID of the resource  the tag is to be attached to.
1015
            resource_type (str): Entity type the tag is to be attached to
1016
            copy (str, optional): UUID of existing tag to clone from
1017
            value (str, optional): Value associated with the tag
1018
            comment (str, optional): Comment for the tag
1019
            active (boolean, optional): Whether the tag should be active
1020
1021
        Returns:
1022
            The response. See :py:meth:`send_command` for details.
1023
        """
1024
        cmd = XmlCommand('create_tag')
1025
        cmd.add_element('name', name)
1026
        _xmlresource = cmd.add_element('resource',
1027
                                       attrs={'id': str(resource_id)})
1028
        _xmlresource.add_element('type', resource_type)
1029
1030
        if comment:
1031
            cmd.add_element('comment', comment)
1032
1033
        if copy:
1034
            cmd.add_element('copy', copy)
1035
1036
        if value:
1037
            cmd.add_element('value', value)
1038
1039
        if not active is None:
1040
            if active:
1041
                cmd.add_element('active', '1')
1042
            else:
1043
                cmd.add_element('active', '0')
1044
1045
        return self._send_xml_command(cmd)
1046
1047
    def create_target(self, name, make_unique=False, asset_hosts_filter=None,
0 ignored issues
show
best-practice introduced by
Too many arguments (18/15)
Loading history...
Comprehensibility introduced by
This function exceeds the maximum number of variables (22/15).
Loading history...
1048
                      hosts=None, comment=None, copy=None, exclude_hosts=None,
1049
                      ssh_credential_id=None, ssh_credential_port=None,
1050
                      smb_credential_id=None, esxi_credential_id=None,
1051
                      snmp_credential_id=None, alive_tests=None,
1052
                      reverse_lookup_only=None, reverse_lookup_unify=None,
1053
                      port_range=None, port_list_id=None):
1054
        """Create a new target
1055
1056
        Arguments:
1057
            name (str): Name of the target
1058
            make_unique (boolean, optional): Append a unique suffix if the name
1059
                already exists
1060
            asset_hosts_filter (str, optional): Filter to select target host
1061
                from assets hosts
1062
            hosts (list, optional): List of hosts addresses to scan
1063
            exclude_hosts (list, optional): List of hosts addresses to exclude
1064
                from scan
1065
            comment (str, optional): Comment for the target
1066
            copy (str, optional): UUID of an existing target to clone from
1067
            ssh_credential_id (str, optional): UUID of a ssh credential to use
1068
                on target
1069
            ssh_credential_port (str, optional): The port to use for ssh
1070
                credential
1071
            smb_credential_id (str, optional): UUID of a smb credential to use
1072
                on target
1073
            snmp_credential_id (str, optional): UUID of a snmp credential to use
1074
                on target
1075
            esxi_credential_id (str, optional): UUID of a esxi credential to use
1076
                on target
1077
            alive_tests (str, optional): Which alive tests to use
1078
            reverse_lookup_only (boolean, optional): Whether to scan only hosts
1079
                that have names
1080
            reverse_lookup_unify (boolean, optional): Whether to scan only one
1081
                IP when multiple IPs have the same name.
1082
            port_range (str, optional): Port range for the target
1083
            port_list_id (str, optional): UUID of the port list to use on target
1084
1085
        Returns:
1086
            The response. See :py:meth:`send_command` for details.
1087
        """
1088
        if not name:
1089
            raise RequiredArgument('create_target requires a name argument')
1090
1091
        cmd = XmlCommand('create_target')
1092
        _xmlname = cmd.add_element('name', name)
1093
        if make_unique:
1094
            _xmlname.add_element('make_unique', '1')
1095
1096
        if asset_hosts_filter:
1097
            cmd.add_element('asset_hosts',
1098
                            attrs={'filter': str(asset_hosts_filter)})
1099
        elif hosts:
1100
            cmd.add_element('hosts', ', '.join(hosts))
1101
        else:
1102
            raise RequiredArgument('create_target requires either a hosts or '
1103
                                   'an asset_hosts_filter argument')
1104
1105
        if comment:
1106
            cmd.add_element('comment', comment)
1107
1108
        if copy:
1109
            # TODO move copy case into clone_target method
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
1110
1111
            # NOTE: It seems that hosts/asset_hosts is silently ignored by the
1112
            # server when copy is supplied. But for specification conformance
1113
            # we raise the ValueError above and consider copy optional.
1114
            cmd.add_element('copy', copy)
1115
1116
        if exclude_hosts:
1117
            cmd.add_element('exclude_hosts', ', '.join(exclude_hosts))
1118
1119
        if ssh_credential_id:
1120
            _xmlssh = cmd.add_element('ssh_credential',
1121
                                      attrs={'id': ssh_credential_id})
1122
            if ssh_credential_port:
1123
                _xmlssh.add_element('port', ssh_credential_port)
1124
1125
        if smb_credential_id:
1126
            cmd.add_element('smb_credential', attrs={'id': smb_credential_id})
1127
1128
        if esxi_credential_id:
1129
            cmd.add_element('esxi_credential', attrs={'id': esxi_credential_id})
1130
1131
        if snmp_credential_id:
1132
            cmd.add_element('snmp_credential', attrs={'id': snmp_credential_id})
1133
1134
        if alive_tests:
1135
            cmd.add_element('alive_tests', alive_tests)
1136
1137
        if not reverse_lookup_only is None:
1138
            if reverse_lookup_only:
1139
                cmd.add_element('reverse_lookup_only', '1')
1140
            else:
1141
                cmd.add_element('reverse_lookup_only', '0')
1142
1143
        if not reverse_lookup_unify is None:
1144
            if reverse_lookup_unify:
1145
                cmd.add_element('reverse_lookup_unify', '1')
1146
            else:
1147
                cmd.add_element('reverse_lookup_unify', '0')
1148
1149
        if port_range:
1150
            cmd.add_element('port_range', port_range)
1151
1152
        if port_list_id:
1153
            cmd.add_element('port_list', attrs={'id': port_list_id})
1154
1155
        return self._send_xml_command(cmd)
1156
1157
    def create_task(self, name, config_id, target_id, scanner_id,
1158
                    alterable=None, hosts_ordering=None, schedule_id=None,
1159
                    alert_ids=None, comment=None, schedule_periods=None,
1160
                    observers=None):
1161
        """Create a new task
1162
1163
        Arguments:
1164
            name (str): Name of the task
1165
            config_id (str): UUID of scan config to use by the task
1166
            target_id (str): UUID of target to be scanned
1167
            scanner_id (str): UUID of scanner to use for scanning the target
1168
            comment (str, optional): Comment for the task
1169
            alterable (boolean, optional): Wether the task should be alterable
1170
            alert_ids (list, optional): List of UUIDs for alerts to be applied
1171
                to the task
1172
            hosts_ordering (str, optional): The order hosts are scanned in
1173
            schedule_id (str, optional): UUID of a schedule when the task should
1174
                be run.
1175
            schedule_periods (int, optional): A limit to the number of times the
1176
                task will be scheduled, or 0 for no limit
1177
            observers (list, optional): List of user names which should be
1178
                allowed to observe this task
1179
1180
        Returns:
1181
            The response. See :py:meth:`send_command` for details.
1182
        """
1183
        if not name:
1184
            raise RequiredArgument('create_task requires a name argument')
1185
1186
        if not config_id:
1187
            raise RequiredArgument('create_task requires a config_id argument')
1188
1189
        if not target_id:
1190
            raise RequiredArgument('create_task requires a target_id argument')
1191
1192
        if not scanner_id:
1193
            raise RequiredArgument('create_task requires a scanner_id argument')
1194
1195
        cmd = XmlCommand('create_task')
1196
        cmd.add_element('name', name)
1197
        cmd.add_element('config', attrs={'id': config_id})
1198
        cmd.add_element('target', attrs={'id': target_id})
1199
        cmd.add_element('scanner', attrs={'id': scanner_id})
1200
1201
        if comment:
1202
            cmd.add_element('comment', comment)
1203
1204
        if not alterable is None:
1205
            if alterable:
1206
                cmd.add_element('alterable', '1')
1207
            else:
1208
                cmd.add_element('alterable', '0')
1209
1210
        if hosts_ordering:
1211
            cmd.add_element('hosts_ordering', hosts_ordering)
1212
1213
        if alert_ids:
1214
            if isinstance(alert_ids, str):
1215
                logger.warning(
1216
                    'Please pass a list as alert_ids parameter to create_task. '
1217
                    'Passing a string is deprecated and will be removed in '
1218
                    'future.')
1219
1220
                #if a single id is given as a string wrap it into a list
1221
                alert_ids = [alert_ids]
1222
            if isinstance(alert_ids, list):
1223
                #parse all given alert id's
1224
                for alert in alert_ids:
1225
                    cmd.add_element('alert', attrs={'id': str(alert)})
1226
1227
        if schedule_id:
1228
            cmd.add_element('schedule', schedule_id)
1229
1230
            if schedule_periods:
1231
                cmd.add_element('schedule_periods', str(schedule_periods))
1232
1233
        if observers:
1234
            cmd.add_element('observers', ' '.join(observers))
1235
1236
        return self._send_xml_command(cmd)
1237
1238
    def create_user(self, name, password=None, copy=None, hosts=None,
1239
                    hosts_allow=False, ifaces=None, ifaces_allow=False,
1240
                    role_ids=None):
1241
        """Create a new user
1242
1243
        Arguments:
1244
            name (str): Name of the user
1245
            password (str, optional): Password of the user
1246
            copy (str, optinal): UUID of existing user to clone from
1247
            hosts (list, optional): A list of host addresses (IPs, DNS names)
1248
            hosts_allow (boolean, optional): If True allow only access to passed
1249
                hosts otherwise deny access. Default is False for deny hosts.
1250
            ifaces (list, optional): A list of interface names
1251
            ifaces_allow (boolean, optional): If True allow only access to
1252
                passed interfaces otherwise deny access. Default is False for
1253
                deny interfaces.
1254
            role_ids (list, optional): A list of role UUIDs for the user
1255
1256
        Returns:
1257
            The response. See :py:meth:`send_command` for details.
1258
        """
1259
        if not name:
1260
            raise RequiredArgument('create_user requires a name argument')
1261
1262
        cmd = XmlCommand('create_user')
1263
        cmd.add_element('name', name)
1264
1265
        if copy:
1266
            cmd.add_element('copy', copy)
1267
1268
        if password:
1269
            cmd.add_element('password', password)
1270
1271
        if hosts:
1272
            cmd.add_element('hosts', ', '.join(hosts),
1273
                            attrs={'allow': '1' if hosts_allow else '0'})
1274
1275
        if ifaces:
1276
            cmd.add_element('ifaces', ', '.join(ifaces),
1277
                            attrs={'allow': '1' if ifaces_allow else '0'})
1278
1279
        if role_ids:
1280
            for role in role_ids:
1281
                cmd.add_element('role', attrs={'id': role})
1282
1283
        return self._send_xml_command(cmd)
1284
1285
    def delete_agent(self, **kwargs):
1286
        cmd = self._generator.delete_agent_command(kwargs)
1287
        return self.send_command(cmd)
1288
1289
    def delete_alert(self, **kwargs):
1290
        cmd = self._generator.delete_alert_command(kwargs)
1291
        return self.send_command(cmd)
1292
1293
    def delete_asset(self, asset_id, ultimate=0):
1294
        cmd = self._generator.delete_asset_command(asset_id, ultimate)
1295
        return self.send_command(cmd)
1296
1297
    def delete_config(self, config_id, ultimate=0):
1298
        cmd = self._generator.delete_config_command(config_id, ultimate)
1299
        return self.send_command(cmd)
1300
1301
    def delete_credential(self, credential_id, ultimate=0):
1302
        cmd = self._generator.delete_credential_command(credential_id, ultimate)
1303
        return self.send_command(cmd)
1304
1305
    def delete_filter(self, filter_id, ultimate=0):
1306
        cmd = self._generator.delete_filter_command(filter_id, ultimate)
1307
        return self.send_command(cmd)
1308
1309
    def delete_group(self, group_id, ultimate=0):
1310
        cmd = self._generator.delete_group_command(group_id, ultimate)
1311
        return self.send_command(cmd)
1312
1313
    def delete_note(self, note_id, ultimate=0):
1314
        cmd = self._generator.delete_note_command(note_id, ultimate)
1315
        return self.send_command(cmd)
1316
1317
    def delete_override(self, override_id, ultimate=0):
1318
        cmd = self._generator.delete_override_command(override_id, ultimate)
1319
        return self.send_command(cmd)
1320
1321
    def delete_permission(self, permission_id, ultimate=0):
1322
        cmd = self._generator.delete_permission_command(permission_id, ultimate)
1323
        return self.send_command(cmd)
1324
1325
    def delete_port_list(self, port_list_id, ultimate=0):
1326
        cmd = self._generator.delete_port_list_command(port_list_id, ultimate)
1327
        return self.send_command(cmd)
1328
1329
    def delete_port_range(self, port_range_id):
1330
        cmd = self._generator.delete_port_range_command(port_range_id)
1331
        return self.send_command(cmd)
1332
1333
    def delete_report(self, report_id):
1334
        cmd = self._generator.delete_report_command(report_id)
1335
        return self.send_command(cmd)
1336
1337
    def delete_report_format(self, report_format_id, ultimate=0):
1338
        cmd = self._generator.delete_report_format_command(
1339
            report_format_id, ultimate)
1340
        return self.send_command(cmd)
1341
1342
    def delete_role(self, role_id, ultimate=0):
1343
        cmd = self._generator.delete_role_command(role_id, ultimate)
1344
        return self.send_command(cmd)
1345
1346
    def delete_scanner(self, scanner_id, ultimate=0):
1347
        cmd = self._generator.delete_scanner_command(scanner_id, ultimate)
1348
        return self.send_command(cmd)
1349
1350
    def delete_schedule(self, schedule_id, ultimate=0):
1351
        cmd = self._generator.delete_schedule_command(schedule_id, ultimate)
1352
        return self.send_command(cmd)
1353
1354
    def delete_tag(self, tag_id, ultimate=0):
1355
        cmd = self._generator.delete_tag_command(tag_id, ultimate)
1356
        return self.send_command(cmd)
1357
1358
    def delete_target(self, target_id, ultimate=0):
1359
        cmd = self._generator.delete_target_command(target_id, ultimate)
1360
        return self.send_command(cmd)
1361
1362
    def delete_task(self, task_id, ultimate=0):
1363
        cmd = self._generator.delete_task_command(task_id, ultimate)
1364
        return self.send_command(cmd)
1365
1366
    def delete_user(self, **kwargs):
1367
        cmd = self._generator.delete_user_command(kwargs)
1368
        return self.send_command(cmd)
1369
1370
    def describe_auth(self):
1371
        cmd = self._generator.describe_auth_command()
1372
        return self.send_command(cmd)
1373
1374
    def empty_trashcan(self):
1375
        cmd = self._generator.empty_trashcan_command()
1376
        return self.send_command(cmd)
1377
1378
    def get_agents(self, **kwargs):
1379
        cmd = self._generator.get_agents_command(kwargs)
1380
        return self.send_command(cmd)
1381
1382
    def get_aggregates(self, **kwargs):
1383
        cmd = self._generator.get_aggregates_command(kwargs)
1384
        return self.send_command(cmd)
1385
1386
    def get_alerts(self, **kwargs):
1387
        cmd = self._generator.get_alerts_command(kwargs)
1388
        return self.send_command(cmd)
1389
1390
    def get_assets(self, **kwargs):
1391
        cmd = self._generator.get_assets_command(kwargs)
1392
        return self.send_command(cmd)
1393
1394
    def get_credentials(self, **kwargs):
1395
        cmd = self._generator.get_credentials_command(kwargs)
1396
        return self.send_command(cmd)
1397
1398
    def get_configs(self, **kwargs):
1399
        cmd = self._generator.get_configs_command(kwargs)
1400
        return self.send_command(cmd)
1401
1402
    def get_feeds(self, **kwargs):
1403
        cmd = self._generator.get_feeds_command(kwargs)
1404
        return self.send_command(cmd)
1405
1406
    def get_filters(self, **kwargs):
1407
        cmd = self._generator.get_filters_command(kwargs)
1408
        return self.send_command(cmd)
1409
1410
    def get_groups(self, **kwargs):
1411
        cmd = self._generator.get_groups_command(kwargs)
1412
        return self.send_command(cmd)
1413
1414
    def get_info(self, **kwargs):
1415
        cmd = self._generator.get_info_command(kwargs)
1416
        return self.send_command(cmd)
1417
1418
    def get_notes(self, **kwargs):
1419
        cmd = self._generator.get_notes_command(kwargs)
1420
        return self.send_command(cmd)
1421
1422
    def get_nvts(self, **kwargs):
1423
        cmd = self._generator.get_nvts_command(kwargs)
1424
        return self.send_command(cmd)
1425
1426
    def get_nvt_families(self, **kwargs):
1427
        cmd = self._generator.get_nvt_families_command(kwargs)
1428
        return self.send_command(cmd)
1429
1430
    def get_overrides(self, **kwargs):
1431
        cmd = self._generator.get_overrides_command(kwargs)
1432
        return self.send_command(cmd)
1433
1434
    def get_permissions(self, **kwargs):
1435
        cmd = self._generator.get_permissions_command(kwargs)
1436
        return self.send_command(cmd)
1437
1438
    def get_port_lists(self, **kwargs):
1439
        cmd = self._generator.get_port_lists_command(kwargs)
1440
        return self.send_command(cmd)
1441
1442
    def get_preferences(self, **kwargs):
1443
        cmd = self._generator.get_preferences_command(kwargs)
1444
        return self.send_command(cmd)
1445
1446
    def get_reports(self, **kwargs):
1447
        cmd = self._generator.get_reports_command(kwargs)
1448
        return self.send_command(cmd)
1449
1450
    def get_report_formats(self, **kwargs):
1451
        cmd = self._generator.get_report_formats_command(kwargs)
1452
        return self.send_command(cmd)
1453
1454
    def get_results(self, **kwargs):
1455
        cmd = self._generator.get_results_command(kwargs)
1456
        return self.send_command(cmd)
1457
1458
    def get_roles(self, **kwargs):
1459
        cmd = self._generator.get_roles_command(kwargs)
1460
        return self.send_command(cmd)
1461
1462
    def get_scanners(self, **kwargs):
1463
        cmd = self._generator.get_scanners_command(kwargs)
1464
        return self.send_command(cmd)
1465
1466
    def get_schedules(self, **kwargs):
1467
        cmd = self._generator.get_schedules_command(kwargs)
1468
        return self.send_command(cmd)
1469
1470
    def get_settings(self, **kwargs):
1471
        cmd = self._generator.get_settings_command(kwargs)
1472
        return self.send_command(cmd)
1473
1474
    def get_system_reports(self, **kwargs):
1475
        cmd = self._generator.get_system_reports_command(kwargs)
1476
        return self.send_command(cmd)
1477
1478
    def get_tags(self, **kwargs):
1479
        cmd = self._generator.get_tags_command(kwargs)
1480
        return self.send_command(cmd)
1481
1482
    def get_targets(self, **kwargs):
1483
        cmd = self._generator.get_targets_command(kwargs)
1484
        return self.send_command(cmd)
1485
1486
    def get_tasks(self, **kwargs):
1487
        cmd = self._generator.get_tasks_command(kwargs)
1488
        return self.send_command(cmd)
1489
1490
    def get_users(self, **kwargs):
1491
        cmd = self._generator.get_users_command(kwargs)
1492
        return self.send_command(cmd)
1493
1494
    def get_version(self):
1495
        cmd = self._generator.get_version_command()
1496
        return self.send_command(cmd)
1497
1498
    def help(self, **kwargs):
1499
        cmd = self._generator.help_command(kwargs)
1500
        return self.send_command(cmd)
1501
1502
    def modify_agent(self, agent_id, name=None, comment=None):
1503
        """Generates xml string for modify agent on gvmd
1504
1505
        Arguments:
1506
            agent_id (str) UUID of the agent to be modified.
1507
            name (str, optional): Name of the new credential
1508
            comment (str, optional): Comment for the credential
1509
        """
1510
        if not agent_id:
1511
            raise RequiredArgument('modify_agent requires agent_id argument')
1512
1513
        cmd = XmlCommand('modify_agent')
1514
        cmd.set_attribute('agent_id', str(agent_id))
1515
        if name:
1516
            cmd.add_element('name', name)
1517
        if comment:
1518
            cmd.add_element('comment', comment)
1519
1520
        return self._send_xml_command(cmd)
1521
1522
    def modify_alert(self, alert_id, name=None, comment=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (19/15).
Loading history...
1523
                     filter_id=None, event= None, event_data=None,
0 ignored issues
show
Coding Style introduced by
No space allowed after keyword argument assignment
Loading history...
1524
                     condition=None, condition_data=None, method=None,
1525
                     method_data=None):
1526
        """Generates xml string for modify alert on gvmd.
1527
1528
        Arguments:
1529
            alert_id (str) UUID of the alert to be modified.
1530
            name (str, optional): Name of the Alert.
1531
            condition (str): The condition that must be satisfied for the alert
1532
                to occur.
1533
            condition_data (dict, optional): Data that defines the condition
1534
            event (str, optional): The event that must happen for the alert
1535
               to occur.
1536
            event_data (dict, optional): Data that defines the event
1537
            method (str, optional): The method by which the user is alerted
1538
            method_data (dict, optional): Data that defines the method
1539
            filter_id (str, optional): Filter to apply when executing alert
1540
            comment (str, optional): Comment for the alert
1541
        """
1542
1543
        if not alert_id:
1544
            raise RequiredArgument('modify_alert requires an alert_id argument')
1545
1546
        cmd = XmlCommand('modify_alert')
1547
        cmd.set_attribute('alert_id', str(alert_id))
1548
1549
        if name:
1550
            cmd.add_element('name', name)
1551
1552
        if comment:
1553
            cmd.add_element('comment', comment)
1554
1555
        if filter_id:
1556
            cmd.add_element('filter', attrs={'id': filter_id})
1557
1558
        conditions = cmd.add_element('condition', condition)
1559
1560
        if not condition_data is None:
1561
            for value, key in condition_data.items():
1562
                _data = conditions.add_element('data', value)
1563
                _data.add_element('name', key)
1564
1565
        events = cmd.add_element('event', event)
1566
1567
        if not event_data is None:
1568
            for value, key in event_data.items():
1569
                _data = events.add_element('data', value)
1570
                _data.add_element('name', key)
1571
1572
        methods = cmd.add_element('method', method)
1573
1574
        if not method_data is None:
1575
            for value, key in method_data.items():
1576
                _data = methods.add_element('data', value)
1577
                _data.add_element('name', key)
1578
1579
        return self._send_xml_command(cmd)
1580
1581
    def modify_asset(self, asset_id, comment):
1582
        """Generates xml string for modify asset on gvmd
1583
1584
        Arguments:
1585
            asset_id (str) UUID of the asset to be modified.
1586
            comment (str, optional): Comment for the asset.
1587
        """
1588
        if not asset_id:
1589
            raise RequiredArgument('modify_asset requires an asset_id argument')
1590
1591
        cmd = XmlCommand('modify_asset')
1592
        cmd.set_attribute('asset_id', asset_id)
1593
        cmd.add_element('comment', comment)
1594
1595
        return self._send_xml_command(cmd)
1596
1597
    def modify_auth(self, group_name, auth_conf_settings):
1598
        """Generates xml string for modify auth on gvmd.
1599
        Arguments:
1600
            group_name (str) Name of the group to be modified.
1601
            auth_conf_settings (dict): The new auth config.
1602
        """
1603
        if not group_name:
1604
            raise RequiredArgument('modify_auth requires a group_name argument')
1605
        if not auth_conf_settings:
1606
            raise RequiredArgument('modify_auth requires an '
1607
                                   'auth_conf_settings argument')
1608
        cmd = XmlCommand('modify_auth')
1609
        _xmlgroup = cmd.add_element('group', attrs={'name': str(group_name)})
1610
1611
        for key, value in auth_conf_settings.items():
1612
            _xmlauthconf = _xmlgroup.add_element('auth_conf_setting')
1613
            _xmlauthconf.add_element('key', key)
1614
            _xmlauthconf.add_element('value', value)
1615
1616
        return self._send_xml_command(cmd)
1617
1618
    def modify_config(self, selection, config_id=None, nvt_oids=None, name=None,
1619
                      value=None, family=None):
1620
        """Modifies an existing scan config on gvmd.
1621
1622
        Arguments:
1623
            selection (str): one of 'nvt_pref', nvt_selection or
1624
                family_selection'
1625
            config_id (str, optional): UUID of scan config to modify.
1626
            name (str, optional): New name for preference.
1627
            value(str, optional): New value for preference.
1628
            nvt_oids (list, optional): List of NVTs associated with preference
1629
                to modify.
1630
            family (str,optional): Name of family to modify.
1631
        """
1632
        if selection not in ('nvt_pref', 'scan_pref',
1633
                             'family_selection', 'nvt_selection'):
1634
            raise InvalidArgument('selection must be one of nvt_pref, '
1635
                                   'sca_pref, family_selection or '
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (remove 1 space).
Loading history...
1636
                                   'nvt_selection')
1637
1638
        cmd = XmlCommand('modify_config')
1639
        cmd.set_attribute('config_id', str(config_id))
1640
1641
        if selection == 'nvt_pref':
1642
            _xmlpref = cmd.add_element('preference')
1643
            if not nvt_oids:
1644
                raise InvalidArgument('modify_config requires a nvt_oids '
1645
                                      'argument')
1646
            _xmlpref.add_element('nvt', attrs={'oid': nvt_oids[0]})
1647
            _xmlpref.add_element('name', name)
1648
            _xmlpref.add_element('value', value)
1649
1650
        elif selection == 'nvt_selection':
1651
            _xmlnvtsel = cmd.add_element('nvt_selection')
1652
            _xmlnvtsel.add_element('family', family)
1653
1654
            if nvt_oids:
1655
                for nvt in nvt_oids:
1656
                    _xmlnvtsel.add_element('nvt', attrs={'oid': nvt})
1657
            else:
1658
                raise InvalidArgument('modify_config requires a nvt_oid '
1659
                                      'argument')
1660
1661
        elif selection == 'family_selection':
1662
            _xmlfamsel = cmd.add_element('family_selection')
1663
            _xmlfamsel.add_element('growing', '1')
1664
            _xmlfamily = _xmlfamsel.add_element('family')
1665
            _xmlfamily.add_element('name', family)
1666
            _xmlfamily.add_element('all', '1')
1667
            _xmlfamily.add_element('growing', '1')
1668
1669
        return self._send_xml_command(cmd)
1670
1671
    def modify_credential(self, credential_id, name=None, comment=None,
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (19/15).
Loading history...
1672
                          allow_insecure=None, certificate=None,
1673
                          key_phrase=None, private_key=None, login=None,
1674
                          password=None, auth_algorithm=None, community=None,
1675
                          privacy_algorithm=None, privacy_password=None,
1676
                          credential_type=None):
1677
        """Generates xml string for modify credential on gvmd.
1678
1679
        Arguments:
1680
            credential_id (str): UUID of the credential
1681
            name (str, optional): Name of the credential
1682
            comment (str, optional): Comment for the credential
1683
            allow_insecure (boolean, optional): Whether to allow insecure use of
1684
                 the credential
1685
            certificate (str, optional): Certificate for the credential
1686
            key_phrase (str, optional): Key passphrase for the private key
1687
            private_key (str, optional): Private key to use for login
1688
            login (str, optional): Username for the credential
1689
            password (str, optional): Password for the credential
1690
            auth_algorithm (str, optional): The auth_algorithm,
1691
                either md5 or sha1.
1692
            community (str, optional): The SNMP community
1693
            privacy_algorithm (str, optional): The SNMP privacy algorithm,
1694
                either aes or des.
1695
            privacy_password (str, optional): The SNMP privacy password
1696
            credential_type (str, optional): The credential type. One of 'cc',
1697
                'snmp', 'up', 'usk'
1698
        """
1699
        if not credential_id:
1700
            raise RequiredArgument('modify_credential requires '
1701
                                   'a credential_id attribute')
1702
1703
        cmd = XmlCommand('modify_credential')
1704
        cmd.set_attribute('credential_id', credential_id)
1705
1706
        if comment:
1707
            cmd.add_element('comment', comment)
1708
1709
        if name:
1710
            cmd.add_element('name', name)
1711
1712
        if allow_insecure:
1713
            cmd.add_element('allow_insecure', allow_insecure)
1714
1715
        if certificate:
1716
            cmd.add_element('certificate', certificate)
1717
1718
        if key_phrase or private_key:
1719
            if not key_phrase or not private_key:
1720
                raise RequiredArgument('modify_credential requires '
1721
                                       'a key_phrase and private_key arguments')
1722
            _xmlkey = cmd.add_element('key')
1723
            _xmlkey.add_element('phrase', key_phrase)
1724
            _xmlkey.add_element('private', private_key)
1725
1726
        if login:
1727
            cmd.add_element('login', login)
1728
1729
        if password:
1730
            cmd.add_element('password', password)
1731
1732
        if auth_algorithm:
1733
            if auth_algorithm not in ('md5', 'sha1'):
1734
                raise RequiredArgument('modify_credential requires '
1735
                                       'auth_algorithm to be either '
1736
                                       'md5 or sha1')
1737
            cmd.add_element('auth_algorithm', auth_algorithm)
1738
1739
        if community:
1740
            cmd.add_element('community', community)
1741
1742
        if privacy_algorithm:
1743
            if privacy_algorithm not in ('aes', 'des'):
1744
                raise RequiredArgument('modify_credential requires '
1745
                                       'privacy_algorithm to be either'
1746
                                       'aes or des')
1747
            _xmlprivacy = cmd.add_element('privacy')
1748
            _xmlprivacy.add_element('algorithm', privacy_algorithm)
1749
            _xmlprivacy.add_element('password', privacy_password)
1750
1751
        if cred_type:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable cred_type does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
Undefined variable 'cred_type'
Loading history...
1752
            if cred_type not in ('cc', 'snmp', 'up', 'usk'):
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'cred_type'
Loading history...
1753
                raise RequiredArgument('modify_credential requires type '
1754
                                 'to be either cc, snmp, up or usk')
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 6 spaces).
Loading history...
1755
            cmd.add_element('type', credential_type)
1756
1757
        return self._send_xml_command(cmd)
1758
1759
    def modify_filter(self, filter_id, comment=None, name=None, term=None,
1760
                      filter_type=None):
1761
        """Generates xml string for modify filter on gvmd.
1762
1763
        Arguments:
1764
            filter_id (str): UUID of the filter to be modified
1765
            comment (str, optional): Comment on filter.
1766
            name (str, optional): Name of filter.
1767
            term (str, optional): Filter term.
1768
            filter_type (str, optional): Resource type filter applies to.
1769
        """
1770
        if not filter_id:
1771
            raise RequiredArgument('modify_filter requires a filter_id '
1772
                                   'attribute')
1773
1774
        cmd = XmlCommand('modify_filter')
1775
        cmd.set_attribute('filter_id', filter_id)
1776
1777
        if comment:
1778
            cmd.add_element('comment', comment)
1779
1780
        if name:
1781
            cmd.add_element('name', name)
1782
1783
        if term:
1784
            cmd.add_element('term', term)
1785
1786
        if filter_type:
1787
            filter_type = filter_type.lower()
1788
            if filter_type not in FILTER_TYPES:
1789
                raise InvalidArgument(
1790
                    'modify_filter requires type to be one of {0} but '
1791
                    'was {1}'.format(', '.join(FILTER_TYPES), filter_type))
1792
            cmd.add_element('type', filter_type)
1793
1794
        return self._send_xml_command(cmd)
1795
1796
    def modify_group(self, group_id, **kwargs):
1797
        cmd = self._generator.modify_group_command(group_id, kwargs)
1798
        return self.send_command(cmd)
1799
1800
    def modify_note(self, note_id, text, **kwargs):
1801
        cmd = self._generator.modify_note_command(note_id, text, kwargs)
1802
        return self.send_command(cmd)
1803
1804
    def modify_override(self, override_id, text, **kwargs):
1805
        cmd = self._generator.modify_override_command(override_id, text,
1806
                                                      kwargs)
1807
        return self.send_command(cmd)
1808
1809
    def modify_permission(self, permission_id, **kwargs):
1810
        cmd = self._generator.modify_permission_command(
1811
            permission_id, kwargs)
1812
        return self.send_command(cmd)
1813
1814
    def modify_port_list(self, port_list_id, **kwargs):
1815
        cmd = self._generator.modify_port_list_command(port_list_id, kwargs)
1816
        return self.send_command(cmd)
1817
1818
    def modify_report(self, report_id, comment):
1819
        cmd = self._generator.modify_report_format_command(report_id, comment)
1820
        return self.send_command(cmd)
1821
1822
    def modify_report_format(self, report_format_id, **kwargs):
1823
        cmd = self._generator.modify_report_format_command(report_format_id,
1824
                                                           kwargs)
1825
        return self.send_command(cmd)
1826
1827
    def modify_role(self, role_id, **kwargs):
1828
        cmd = self._generator.modify_role_command(role_id, kwargs)
1829
        return self.send_command(cmd)
1830
1831
    def modify_scanner(self, scanner_id, host, port, scanner_type, **kwargs):
1832
        cmd = self._generator.modify_scanner_command(scanner_id, host, port,
1833
                                                     scanner_type, kwargs)
1834
        return self.send_command(cmd)
1835
1836
    def modify_schedule(self, schedule_id, **kwargs):
1837
        cmd = self._generator.modify_schedule_command(schedule_id, kwargs)
1838
        return self.send_command(cmd)
1839
1840
    def modify_setting(self, setting_id, name, value):
1841
        cmd = self._generator.modify_setting_command(setting_id, name, value)
1842
        return self.send_command(cmd)
1843
1844
    def modify_tag(self, tag_id, **kwargs):
1845
        cmd = self._generator.modify_tag_command(tag_id, kwargs)
1846
        return self.send_command(cmd)
1847
1848
    def modify_target(self, target_id, **kwargs):
1849
        cmd = self._generator.modify_target_command(target_id, kwargs)
1850
        return self.send_command(cmd)
1851
1852
    def modify_task(self, task_id, **kwargs):
1853
        cmd = self._generator.modify_task_command(task_id, kwargs)
1854
        return self.send_command(cmd)
1855
1856
    def modify_user(self, **kwargs):
1857
        cmd = self._generator.modify_user_command(kwargs)
1858
        return self.send_command(cmd)
1859
1860
    def move_task(self, task_id, slave_id):
1861
        cmd = self._generator.move_task_command(task_id, slave_id)
1862
        return self.send_command(cmd)
1863
1864
    def restore(self, entity_id):
1865
        cmd = self._generator.restore_command(entity_id)
1866
        return self.send_command(cmd)
1867
1868
    def resume_task(self, task_id):
1869
        cmd = self._generator.resume_task_command(task_id)
1870
        return self.send_command(cmd)
1871
1872
    def start_task(self, task_id):
1873
        cmd = self._generator.start_task_command(task_id)
1874
        return self.send_command(cmd)
1875
1876
    def stop_task(self, task_id):
1877
        cmd = self._generator.stop_task_command(task_id)
1878
        return self.send_command(cmd)
1879
1880
    def sync_cert(self):
1881
        cmd = self._generator.sync_cert_command()
1882
        return self.send_command(cmd)
1883
1884
    def sync_config(self):
1885
        cmd = self._generator.sync_config_command()
1886
        return self.send_command(cmd)
1887
1888
    def sync_feed(self):
1889
        cmd = self._generator.sync_feed_command()
1890
        return self.send_command(cmd)
1891
1892
    def sync_scap(self):
1893
        cmd = self._generator.sync_scap_command()
1894
        return self.send_command(cmd)
1895
1896
    def test_alert(self, alert_id):
1897
        cmd = self._generator.test_alert_command(alert_id)
1898
        return self.send_command(cmd)
1899
1900
    def verify_agent(self, agent_id):
1901
        cmd = self._generator.verify_agent_command(agent_id)
1902
        return self.send_command(cmd)
1903
1904
    def verify_report_format(self, report_format_id):
1905
        cmd = self._generator.verify_report_format_command(report_format_id)
1906
        return self.send_command(cmd)
1907
1908
    def verify_scanner(self, scanner_id):
1909
        cmd = self._generator.verify_scanner_command(scanner_id)
1910
        return self.send_command(cmd)
1911