Passed
Pull Request — master (#13)
by
unknown
01:27
created

ospd_openvas.wrapper.OSPDopenvas.update_progress()   A

Complexity

Conditions 2

Size

Total Lines 12
Code Lines 10

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nop 4
dl 12
loc 12
rs 9.9
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
# Description:
3
# Setup for the OSP OpenVAS Server
4
#
5
# Authors:
6
# Juan José Nicola <[email protected]>
7
#
8
# Copyright:
9
# Copyright (C) 2018 Greenbone Networks GmbH
10
#
11
# This program is free software; you can redistribute it and/or
12
# modify it under the terms of the GNU General Public License
13
# as published by the Free Software Foundation; either version 2
14
# of the License, or (at your option) any later version.
15
#
16
# This program is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
# GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License
22
# along with this program; if not, write to the Free Software
23
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25
import subprocess
26
import time
27
import os
28
import signal
29
import psutil
30
31
from ospd.ospd import OSPDaemon, logger
32
from ospd.misc import main as daemon_main
33
from ospd.misc import target_str_to_list
34
from ospd_openvas import __version__
35
36
import ospd_openvas.nvticache as nvti
37
import ospd_openvas.openvas_db as openvas_db
38
39
OSPD_DESC = """
40
This scanner runs 'OpenVAS Scanner' to scan the target hosts.
41
42
OpenVAS (Open Vulnerability Assessment System) is a powerful scanner
43
for vulnerabilities in IT infrastrucutres. The capabilities include
44
unauthzenticated scanning as well as authneticated scanning for
45
various types of systems and services.
46
47
For more details about OpenVAS see the OpenVAS homepage:
48
http://www.openvas.org/
49
50
The current version of ospd-openvas is a simple frame, which sends
51
the server parameters to the Greenbone Vulnerability Manager (GVM) and checks
52
the existence of OpenVAS Scanner binary. But it can not run scans yet.
53
"""
54
55
MAIN_KBINDEX = None
56
57
OSPD_PARAMS = {
58
    'auto_enable_dependencies': {
59
        'type': 'boolean',
60
        'name': 'auto_enable_dependencies',
61
        'default': 1,
62
        'mandatory': 1,
63
        'description': 'Automatically enable the plugins that are depended on',
64
    },
65
    'cgi_path': {
66
        'type': 'string',
67
        'name': 'cgi_path',
68
        'default': '/cgi-bin:/scripts',
69
        'mandatory': 1,
70
        'description': 'Look for default CGIs in /cgi-bin and /scripts',
71
    },
72
    'checks_read_timeout': {
73
        'type': 'integer',
74
        'name': 'checks_read_timeout',
75
        'default': 5,
76
        'mandatory': 1,
77
        'description': ('Number  of seconds that the security checks will ' +
78
                        'wait for when doing a recv()'),
79
    },
80
    'drop_privileges': {
81
        'type': 'boolean',
82
        'name': 'drop_privileges',
83
        'default': 0,
84
        'mandatory': 1,
85
        'description': '',
86
    },
87
    'network_scan': {
88
        'type': 'boolean',
89
        'name': 'network_scan',
90
        'default': 0,
91
        'mandatory': 1,
92
        'description': '',
93
    },
94
    'non_simult_ports': {
95
        'type': 'string',
96
        'name': 'non_simult_ports',
97
        'default': '139, 445, 3389, Services/irc',
98
        'mandatory': 1,
99
        'description': ('Prevent to make two connections on the same given ' +
100
                        'ports at the same time.'),
101
    },
102
    'open_sock_max_attempts': {
103
        'type': 'integer',
104
        'name': 'open_sock_max_attempts',
105
        'default': 5,
106
        'mandatory': 0,
107
        'description': ('Number of unsuccessful retries to open the socket ' +
108
                        'before to set the port as closed.'),
109
    },
110
    'timeout_retry': {
111
        'type': 'integer',
112
        'name': 'timeout_retry',
113
        'default': 5,
114
        'mandatory': 0,
115
        'description': ('Number of retries when a socket connection attempt ' +
116
                        'timesout.'),
117
    },
118
    'optimize_test': {
119
        'type': 'integer',
120
        'name': 'optimize_test',
121
        'default': 5,
122
        'mandatory': 0,
123
        'description': ('By default, openvassd does not trust the remote ' +
124
                        'host banners.'),
125
    },
126
    'plugins_timeout': {
127
        'type': 'integer',
128
        'name': 'plugins_timeout',
129
        'default': 5,
130
        'mandatory': 0,
131
        'description': 'This is the maximum lifetime, in seconds of a plugin.',
132
    },
133
    'report_host_details': {
134
        'type': 'boolean',
135
        'name': 'report_host_details',
136
        'default': 1,
137
        'mandatory': 1,
138
        'description': '',
139
    },
140
    'safe_checks': {
141
        'type': 'boolean',
142
        'name': 'safe_checks',
143
        'default': 1,
144
        'mandatory': 1,
145
        'description': ('Disable the plugins with potential to crash ' +
146
                        'the remote services'),
147
    },
148
    'scanner_plugins_timeout': {
149
        'type': 'integer',
150
        'name': 'scanner_plugins_timeout',
151
        'default': 36000,
152
        'mandatory': 1,
153
        'description': 'Like plugins_timeout, but for ACT_SCANNER plugins.',
154
    },
155
    'time_between_request': {
156
        'type': 'integer',
157
        'name': 'time_between_request',
158
        'default': 0,
159
        'mandatory': 0,
160
        'description': ('Allow to set a wait time between two actions ' +
161
                        '(open, send, close).'),
162
    },
163
    'unscanned_closed': {
164
        'type': 'boolean',
165
        'name': 'unscanned_closed',
166
        'default': 1,
167
        'mandatory': 1,
168
        'description': '',
169
    },
170
    'unscanned_closed_udp': {
171
        'type': 'boolean',
172
        'name': 'unscanned_closed_udp',
173
        'default': 1,
174
        'mandatory': 1,
175
        'description': '',
176
    },
177
    'use_mac_addr': {
178
        'type': 'boolean',
179
        'name': 'use_mac_addr',
180
        'default': 0,
181
        'mandatory': 0,
182
        'description': 'To test the local network. ' +
183
                       'Hosts will be referred to by their MAC address.',
184
    },
185
    'vhosts': {
186
        'type': 'string',
187
        'name': 'vhosts',
188
        'default': '',
189
        'mandatory': 0,
190
        'description': '',
191
    },
192
    'vhosts_ip': {
193
        'type': 'string',
194
        'name': 'vhosts_ip',
195
        'default': '',
196
        'mandatory': 0,
197
        'description': '',
198
    },
199
}
200
201
202 View Code Duplication
class OSPDopenvas(OSPDaemon):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
Unused Code introduced by
The variable __class__ seems to be unused.
Loading history...
203
204
    """ Class for ospd-openvas daemon. """
205
206
    def __init__(self, certfile, keyfile, cafile):
207
        """ Initializes the ospd-openvas daemon's internal data. """
208
209
        super(OSPDopenvas, self).__init__(certfile=certfile, keyfile=keyfile,
210
                                          cafile=cafile)
211
        self.server_version = __version__
212
        self.scanner_info['name'] = 'openvassd'
213
        self.scanner_info['version'] = ''  # achieved during self.check()
214
        self.scanner_info['description'] = OSPD_DESC
215
        for name, param in OSPD_PARAMS.items():
216
            self.add_scanner_param(name, param)
217
218
        if openvas_db.db_init() is False:
219
            logger.error('OpenVAS Redis Error: Not possible '
220
                         'to find db_connection.')
221
            raise Exception
222
223
        ctx = openvas_db.db_find(nvti.NVTICACHE_STR)
224
        if not ctx:
225
            self.redis_nvticache_init()
226
            ctx = openvas_db.db_find(nvti.NVTICACHE_STR)
227
        openvas_db.set_global_redisctx(ctx)
228
        self.load_vts()
229
230
    def parse_param(self):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
231
        """ Set OSPD_PARAMS with the params taken from the openvas_scanner. """
232
        global OSPD_PARAMS
0 ignored issues
show
Coding Style introduced by
Usage of the global statement should be avoided.

Usage of global can make code hard to read and test, its usage is generally not recommended unless you are dealing with legacy code.

Loading history...
233
        bool_dict = {'no': 0, 'yes': 1}
234
235
        result = subprocess.check_output(['openvassd', '-s'],
236
                                         stderr=subprocess.STDOUT)
237
        result = result.decode('ascii')
238
        param_list = dict()
239
        for conf in result.split('\n'):
240
            elem = conf.split('=')
241
            if len(elem) == 2:
242
                value = str.strip(elem[1])
243
                if str.strip(elem[1]) in bool_dict:
244
                    value = bool_dict[value]
245
                param_list[str.strip(elem[0])] = value
246
        for elem in OSPD_PARAMS:
247
            if elem in param_list:
248
                OSPD_PARAMS[elem]['default'] = param_list[elem]
249
250
    def redis_nvticache_init(self):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
251
        """ Loads NVT's metadata into Redis DB. """
252
        try:
253
            logger.debug('Loading NVTs in Redis DB')
254
            subprocess.check_call(['openvassd', '-C'])
255
        except subprocess.CalledProcessError as err:
256
            logger.error('OpenVAS Scanner failed to load NVTs.')
257
            raise err
258
259
    def load_vts(self):
260
        """ Load the NVT's OIDs and their filename into the vts
261
        global  dictionary. """
262
        oids = nvti.get_oids()
263
        str_out = True
264
        for oid in oids:
265
            vt_id = oid[1]
266
            filename = oid[0].split(':')
267
            ret = self.add_vt(vt_id,
268
                              name=filename[1],
269
                              vt_params=nvti.get_nvt_params(vt_id, str_out),
270
                              custom=nvti.get_nvt_metadata(vt_id, str_out))
271
            if ret == -1:
272
                logger.info("Dupplicated VT with OID: {0}".format(vt_id))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
273
            if ret == -2:
274
                logger.info("{0}: Invalid OID.".format(vt_id))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
275
276
    @staticmethod
277
    def get_custom_vt_as_xml_str(custom):
278
        """ Return custom since it is already formated as string. """
279
        return custom
280
281
    @staticmethod
282
    def get_params_vt_as_xml_str(vt_params):
283
        """ Return custom since it is already formated as string. """
284
        return vt_params
285
286
    def check(self):
287
        """ Checks that openvassd command line tool is found and
288
        is executable. """
289
        try:
290
            result = subprocess.check_output(['openvassd', '-V'],
291
                                             stderr=subprocess.STDOUT)
292
            result = result.decode('ascii')
293
        except OSError:
294
            # The command is not available
295
            return False
296
297
        if result is None:
298
            return False
299
300
        version = result.split('\n')
301
        if version[0].find('OpenVAS') < 0:
302
            return False
303
304
        self.parse_param()
305
        self.scanner_info['version'] = version[0]
306
307
        return True
308
309
    def update_progress(self, scan_id, target, msg):
310
        """ Calculate porcentage and update the scan status
311
        for the progress bar. """
312
        host_progress_dict = dict()
313
        prog = str.split(msg, '/')
314
        if prog[1] == 0:
315
            return
316
        host_prog = (float(prog[0]) / float(prog[1])) * 100
317
        host_progress_dict[target] = host_prog
318
        total_host = len(target_str_to_list(target))
319
        self.set_scan_progress(scan_id,
320
                               sum(host_progress_dict.values()) / total_host)
321
322
    def get_openvas_status(self, scan_id, target):
323
        """ Get all status entries from redis kb. """
324
        res = openvas_db.get_status()
325
        while res:
326
            self.update_progress(scan_id, target, res)
327
            res = openvas_db.get_status()
328
329
    def get_openvas_result(self, scan_id):
330
        """ Get all result entries from redis kb. """
331
        res = openvas_db.get_result()
332
        while res:
333
            msg = res.split('|||')
334
            if msg[1] == '':
335
                host_aux = openvas_db.item_get_single('internal/ip')
336
            else:
337
                host_aux = msg[1]
338
            if msg[0] == 'ERRMSG':
339
                self.add_scan_error(scan_id, host=host_aux,
340
                                    name=msg[3], value=msg[4], port=msg[2])
341
            if msg[0] == 'LOG':
342
                self.add_scan_log(scan_id, host=host_aux, name=msg[3],
343
                                  value=msg[4], port=msg[2])
344
            if msg[0] == 'ALARM':
345
                self.add_scan_alarm(scan_id, host=host_aux, name=msg[3],
346
                                    value=msg[4], port=msg[2], qod='97',
347
                                    severity='7.5')
348
            res = openvas_db.get_result()
349
350
    def get_openvas_timestamp_scan_host(self, scan_id, target):
351
        """ Get start and end timestamp of a host scan from redis kb. """
352
        timestamp = openvas_db.get_host_scan_scan_end_time()
353
        if timestamp:
354
            self.add_scan_log(scan_id, host=target, name='HOST_END',
355
                              value=timestamp)
356
            return
357
        timestamp = openvas_db.get_host_scan_scan_start_time()
358
        if timestamp:
359
            self.add_scan_log(scan_id, host=target, name='HOST_START',
360
                              value=timestamp)
361
            return
362
363
    def scan_is_finished(self, scan_id):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
364
        """ Check if the scan has finished. """
365
        status = openvas_db.item_get_single(('internal/%s' % scan_id))
366
        return status == 'finished'
367
368
    def scan_is_stopped(self, scan_id):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
369
        """ Check if the parent process has recieved the stop_scan order.
370
        @in scan_id: ID to identify the scan to be stopped.
371
        @return 1 if yes, None in oder case.
372
        """
373
        ctx = openvas_db.kb_connect(dbnum=MAIN_KBINDEX)
374
        openvas_db.set_global_redisctx(ctx)
375
        status = openvas_db.item_get_single(('internal/%s' % scan_id))
376
        return status == 'stop_all'
377
378
    def stop_scan(self, scan_id):
379
        """ Set a key in redis to indicate the wrapper process that it
380
        must kill the childs. It is done through redis because this a new
381
        multiprocess instance and it is not possible to reach the variables
382
        of the grandchild process. Then, a clean up is performed before
383
        terminating. """
384
        ctx = openvas_db.db_find('internal/%s' % scan_id)
385
        openvas_db.set_global_redisctx(ctx)
386
        openvas_db.item_set_single(('internal/%s' % scan_id), ['stop_all', ])
387
        while 1:
388
            time.sleep(1)
389
            if openvas_db.item_get_single('internal/%s' % scan_id):
390
                continue
391
            break
392
393
    def do_cleanup(self, ovas_pid):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
394
        """ Send SIGUSR1 to OpenVAS process to stop the scan. """
395
        parent = psutil.Process(ovas_pid)
396
        children = parent.children(recursive=True)
397
        for process in children:
398
            if process.ppid() == int(ovas_pid):
399
                logger.debug('Stopping process: {0}'.format(process))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
400
                os.kill(process.pid, signal.SIGUSR1)
401
402
    @staticmethod
403
    def process_vts(vts):
404
        """ Add single VTs and their parameters. """
405
        vts_list = []
406
        vts_params = []
407
        ctx = openvas_db.db_find(nvti.NVTICACHE_STR)
408
        for memb in vts.items():
409
            vts_list.append(memb[0])
410
            nvt_name = nvti.get_nvt_name(ctx, memb[0])
411
            for i in memb[1].items():
412
                param = ["{0}[{1}]:{2}".format(nvt_name, i[1]['type'], i[0]),
413
                         str(i[1]['value'])]
414
                vts_params.append(param)
415
        return vts_list, vts_params
416
417
    @staticmethod
418
    def build_credentials_as_prefs(credentials):
419
        """ Parse the credential dictionary.
420
        @param credentials: Dictionary with the credentials.
421
422
        @return A list with the credentials in string format to be
423
                added to the redis KB.
424
        """
425
        cred_prefs_list = []
426
        for credential in credentials.items():
427
            service = credential[0]
428
            cred_params = credentials.get(service)
429
            cred_type = cred_params.get('type', '')
430
            username = cred_params.get('username', '')
431
            password = cred_params.get('password', '')
432
433
            if service == 'ssh':
434
                port = cred_params.get('port', '')
435
                cred_prefs_list.append('auth_port_ssh|||' +
436
                                       '{0}'.format(port))
437
                cred_prefs_list.append('SSH Authorization[entry]:SSH login ' +
438
                                       'name:|||{0}'.format(username))
439
                if cred_type == 'up':
440
                    cred_prefs_list.append('SSH Authorization[password]:' +
441
                                           'SSH password (unsafe!):|||' +
442
                                           '{0}'.format(password))
443
                else:
444
                    private = cred_params.get('private', '')
445
                    cred_prefs_list.append('SSH Authorization[password]:' +
446
                                           'SSH key passphrase:|||' +
447
                                           '{0}'.format(password))
448
                    cred_prefs_list.append('SSH Authorization[file]:' +
449
                                           'SSH private key:|||' +
450
                                           '{0}'.format(private))
451
            if service == 'smb':
452
                cred_prefs_list.append('SMB Authorization[entry]:SMB login:' +
453
                                       '|||{0}'.format(username))
454
                cred_prefs_list.append('SMB Authorization[password]:' +
455
                                       'SMB password :|||' +
456
                                       '{0}'.format(password))
457
            if service == 'esxi':
458
                cred_prefs_list.append('ESXi Authorization[entry]:ESXi login ' +
459
                                       'name:|||{0}'.format(username))
460
                cred_prefs_list.append('ESXi Authorization[password]:' +
461
                                       'ESXi login password:|||' +
462
                                       '{0}'.format(password))
463
464
            if service == 'snmp':
465
                community = cred_params.get('community', '')
466
                auth_algorithm = cred_params.get('auth_algorithm', '')
467
                privacy_password = cred_params.get('privacy_password', '')
468
                privacy_algorithm = cred_params.get('privacy_algorithm', '')
469
470
                cred_prefs_list.append('SNMP Authorization[password]:' +
471
                                       'SNMP Community:' +
472
                                       '{0}'.format(community))
473
                cred_prefs_list.append('SNMP Authorization[entry]:' +
474
                                       'SNMPv3 Username:' +
475
                                       '{0}'.format(username))
476
                cred_prefs_list.append('SNMP Authorization[password]:' +
477
                                       'SNMPv3 Password:' +
478
                                       '{0}'.format(password))
479
                cred_prefs_list.append('SNMP Authorization[radio]:' +
480
                                       'SNMPv3 Authentication Algorithm:' +
481
                                       '{0}'.format(auth_algorithm))
482
                cred_prefs_list.append('SNMP Authorization[password]:' +
483
                                       'SNMPv3 Privacy Password:' +
484
                                       '{0}'.format(privacy_password))
485
                cred_prefs_list.append('SNMP Authorization[radio]:' +
486
                                       'SNMPv3 Privacy Algorithm:' +
487
                                       '{0}'.format(privacy_algorithm))
488
489
        return cred_prefs_list
490
491
    def exec_scan(self, scan_id, target):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (25/15).
Loading history...
492
        """ Starts the OpenVAS scanner for scan_id scan. """
493
        global MAIN_KBINDEX
0 ignored issues
show
Coding Style introduced by
Usage of the global statement should be avoided.

Usage of global can make code hard to read and test, its usage is generally not recommended unless you are dealing with legacy code.

Loading history...
494
        ports = self.get_scan_ports(scan_id, target)
495
        if not ports:
496
            self.add_scan_error(scan_id, name='', host=target,
497
                                value='No port list defined.')
498
            return 2
499
500
        # Get scan options
501
        options = self.get_scan_options(scan_id)
502
        prefs_val = []
503
        ctx = openvas_db.kb_new()
504
        openvas_db.set_global_redisctx(ctx)
505
        MAIN_KBINDEX = openvas_db.DB_INDEX
506
507
        openvas_db.item_add_single(('internal/%s' % scan_id), ['new', ])
508
509
        # Set scan preferences
510
        for item in options.items():
511
            prefs_val.append(item[0] + "|||" + str(item[1]))
512
        openvas_db.item_add_single(str('internal/%s/scanprefs' % scan_id),
513
                                   prefs_val)
514
515
        # Set target
516
        target_aux = ('TARGET|||%s' % target)
517
        openvas_db.item_add_single(('internal/%s/scanprefs' % scan_id),
518
                                   [target_aux, ])
519
        # Set port range
520
        port_range = ('port_range|||%s' % ports)
521
        openvas_db.item_add_single(('internal/%s/scanprefs' % scan_id),
522
                                   [port_range, ])
523
524
        # Set credentials
525
        credentials = self.get_scan_credentials(scan_id, target)
0 ignored issues
show
Bug introduced by
The Instance of OSPDopenvas does not seem to have a member named get_scan_credentials.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
526
        if credentials:
527
            cred_prefs = self.build_credentials_as_prefs(credentials)
528
            openvas_db.item_add_single(str('internal/%s/scanprefs' % scan_id),
529
                                       cred_prefs)
530
531
        # Set plugins to run
532
        nvts = self.get_scan_vts(scan_id)
533
        if nvts != '':
534
            nvts_list, nvts_params = self.process_vts(nvts)
535
            # Add nvts list
536
            separ = ';'
537
            plugin_list = ('plugin_set|||%s' % separ.join(nvts_list))
538
            openvas_db.item_add_single(('internal/%s/scanprefs' % scan_id),
539
                                       [plugin_list, ])
540
            # Add nvts parameters
541
            for elem in nvts_params:
542
                item = ('%s|||%s' % (elem[0], elem[1]))
543
                openvas_db.item_add_single(('internal/%s/scanprefs' % scan_id),
544
                                           [item, ])
545
        else:
546
            openvas_db.release_db(MAIN_KBINDEX)
547
            self.add_scan_error(scan_id, name='', host=target,
548
                                value='No VTS to run.')
549
            return 2
550
551
        # Create a general log entry about executing OpenVAS
552
        # It is important to send at least one result, otherwise
553
        # the host details won't be stored.
554
        self.add_scan_log(scan_id, host=target, name='OpenVAS summary',
555
                          value='An OpenVAS Scanner was started for %s.'
556
                          % target)
557
558
        self.add_scan_log(scan_id, host=target, name='KB location Found',
559
                          value='KB location path was found: %s.'
560
                          % openvas_db.DB_ADDRESS)
561
562
        self.add_scan_log(scan_id, host=target, name='Feed Update',
563
                          value='Feed version: %s.'
564
                          % nvti.get_feed_version())
565
566
        cmd = ['openvassd', '--scan-start', scan_id]
567
        try:
568
            result = subprocess.Popen(cmd, shell=False)
569
        except OSError:
570
            # the command is not available
571
            return False
572
573
        ovas_pid = result.pid
574
        logger.debug('pid = {0}'.format(ovas_pid))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
575
576
        no_id_found = False
577
        while 1:
578
            time.sleep(3)
579
580
            # Check if the client stopped the whole scan
581
            if self.scan_is_stopped(scan_id):
582
                self.do_cleanup(ovas_pid)
583
584
            for i in range(1, openvas_db.MAX_DBINDEX):
585
                if i == MAIN_KBINDEX:
586
                    continue
587
                ctx = openvas_db.kb_connect(i)
588
                openvas_db.set_global_redisctx(ctx)
589
                id_aux = openvas_db.item_get_single('internal/scan_id')
590
                if not id_aux:
591
                    continue
592
                if id_aux == scan_id:
593
                    no_id_found = False
594
                    self.get_openvas_timestamp_scan_host(scan_id, target)
595
                    self.get_openvas_result(scan_id)
596
                    self.get_openvas_status(scan_id, target)
597
598
                    if self.scan_is_finished(scan_id):
599
                        openvas_db.release_db(i)
600
            # Scan end. No kb in use for this scan id
601
            if no_id_found:
602
                break
603
            no_id_found = True
604
605
        # Delete keys from KB related to this scan task.
606
        openvas_db.release_db(MAIN_KBINDEX)
607
        return 1
608
609
610
def main():
611
    """ OSP openvas main function. """
612
    daemon_main('OSPD - openvas wrapper', OSPDopenvas)
613