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

gvm.protocols.gmpv7.Gmp.get_overrides()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
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