def process_vts(self, vts): """ Add single VTs and their parameters. """ vts_list = [] vts_params = [] vtgroups = vts.pop('vt_groups') ctx = openvas_db.db_find(nvti.NVTICACHE_STR) openvas_db.set_global_redisctx(ctx) if vtgroups: vts_list = self.get_vts_in_groups(ctx, vtgroups) for vtid, vt_params in vts.items(): vts_list.append(vtid) nvt_name = self.vts[vtid].get('name') for vt_param_id, vt_param_value in vt_params.items(): param_type = self.get_vt_param_type(vtid, vt_param_id) if vt_param_id == 'timeout': type_aux = 'integer' else: type_aux = param_type if self.check_param_type(vt_param_value, type_aux): logger.debug( 'Expected {} type for parameter value {}'.format( type_aux, str(vt_param_value))) param = [ "{0}[{1}]:{2}".format(nvt_name, param_type, vt_param_id), str(vt_param_value) ] vts_params.append(param) return vts_list, vts_params
def __init__(self, certfile, keyfile, cafile): """ Initializes the ospd-openvas daemon's internal data. """ super(OSPDopenvas, self).__init__(certfile=certfile, keyfile=keyfile, cafile=cafile) self.server_version = __version__ self.scanner_info['name'] = 'openvassd' self.scanner_info['version'] = '' # achieved during self.check() self.scanner_info['description'] = OSPD_DESC for name, param in OSPD_PARAMS.items(): self.add_scanner_param(name, param) if openvas_db.db_init() is False: logger.error('OpenVAS Redis Error: Not possible ' 'to find db_connection.') raise Exception self.pending_feed = None ctx = openvas_db.db_find(nvti.NVTICACHE_STR) if not ctx: self.redis_nvticache_init() ctx = openvas_db.db_find(nvti.NVTICACHE_STR) openvas_db.set_global_redisctx(ctx) self.load_vts()
def scan_is_stopped(self, scan_id): """ Check if the parent process has received the stop_scan order. @in scan_id: ID to identify the scan to be stopped. @return 1 if yes, None in other case. """ ctx = openvas_db.kb_connect(dbnum=MAIN_KBINDEX) openvas_db.set_global_redisctx(ctx) status = openvas_db.item_get_single(('internal/%s' % scan_id)) return status == 'stop_all'
def stop_scan(global_scan_id): """ Set a key in redis to indicate the wrapper is stopped. It is done through redis because it is a new multiprocess instance and it is not possible to reach the variables of the grandchild process. Send SIGUSR2 to openvas to stop each running scan.""" ctx = openvas_db.kb_connect() for current_kbi in range(0, openvas_db.MAX_DBINDEX): ctx.execute_command('SELECT ' + str(current_kbi)) openvas_db.set_global_redisctx(ctx) scan_id = openvas_db.item_get_single( ('internal/%s/globalscanid' % global_scan_id)) if scan_id: openvas_db.item_set_single(('internal/%s' % scan_id), [ 'stop_all', ]) ovas_pid = openvas_db.item_get_single('internal/ovas_pid') parent = psutil.Process(int(ovas_pid)) openvas_db.release_db(current_kbi) parent.send_signal(signal.SIGUSR2) logger.debug('Stopping process: {0}'.format(parent))
def exec_scan(self, scan_id, target): """ Starts the OpenVAS scanner for scan_id scan. """ if self.pending_feed: logger.info('%s: There is a pending feed update. ' 'The scan can not be started.' % scan_id) self.add_scan_error( scan_id, name='', host=target, value=('It was not possible to start the scan,' 'because a pending feed update. Please try later')) return 2 global MAIN_KBINDEX ports = self.get_scan_ports(scan_id, target) if not ports: self.add_scan_error(scan_id, name='', host=target, value='No port list defined.') return 2 # Get scan options options = self.get_scan_options(scan_id) prefs_val = [] ctx = openvas_db.kb_new() openvas_db.set_global_redisctx(ctx) MAIN_KBINDEX = openvas_db.DB_INDEX # To avoid interference between scan process during a parallel scanning # new uuid is used internally for each scan. openvas_scan_id = str(uuid.uuid4()) openvas_db.item_add_single(('internal/%s' % openvas_scan_id), [ 'new', ]) openvas_db.item_add_single(('internal/%s/globalscanid' % scan_id), [ openvas_scan_id, ]) # Set scan preferences for item in options.items(): item_type = '' if item[0] in OSPD_PARAMS: item_type = OSPD_PARAMS[item[0]].get('type') if item_type == 'boolean' and item[1] == 1: val = 'yes' else: val = str(item[1]) prefs_val.append(item[0] + "|||" + val) openvas_db.item_add_single( str('internal/%s/scanprefs' % (openvas_scan_id)), prefs_val) # Store MAIN_KBINDEX as global preference ov_maindbid = ('ov_maindbid|||%d' % MAIN_KBINDEX) openvas_db.item_add_single(('internal/%s/scanprefs' % openvas_scan_id), [ ov_maindbid, ]) # Set target target_aux = ('TARGET|||%s' % target) openvas_db.item_add_single(('internal/%s/scanprefs' % openvas_scan_id), [ target_aux, ]) # Set port range port_range = ('port_range|||%s' % ports) openvas_db.item_add_single(('internal/%s/scanprefs' % openvas_scan_id), [ port_range, ]) # Set credentials credentials = self.get_scan_credentials(scan_id, target) if credentials: cred_prefs = self.build_credentials_as_prefs(credentials) openvas_db.item_add_single( str('internal/%s/scanprefs' % openvas_scan_id), cred_prefs) # Set plugins to run nvts = self.get_scan_vts(scan_id) if nvts != '': nvts_list, nvts_params = self.process_vts(nvts) # Select the scan KB again. ctx.execute_command('SELECT ' + str(MAIN_KBINDEX)) openvas_db.set_global_redisctx(ctx) # Add nvts list separ = ';' plugin_list = ('plugin_set|||%s' % separ.join(nvts_list)) openvas_db.item_add_single( ('internal/%s/scanprefs' % openvas_scan_id), [ plugin_list, ]) # Add nvts parameters for elem in nvts_params: item = ('%s|||%s' % (elem[0], elem[1])) openvas_db.item_add_single( ('internal/%s/scanprefs' % openvas_scan_id), [ item, ]) else: openvas_db.release_db(MAIN_KBINDEX) self.add_scan_error(scan_id, name='', host=target, value='No VTS to run.') return 2 # Create a general log entry about executing OpenVAS # It is important to send at least one result, otherwise # the host details won't be stored. self.add_scan_log(scan_id, host=target, name='OpenVAS summary', value='An OpenVAS Scanner was started for %s.' % target) self.add_scan_log(scan_id, host=target, name='KB location Found', value='KB location path was found: %s.' % openvas_db.DB_ADDRESS) self.add_scan_log(scan_id, host=target, name='Feed Update', value='Feed version: %s.' % nvti.get_feed_version()) cmd = ['openvassd', '--scan-start', openvas_scan_id] try: result = subprocess.Popen(cmd, shell=False) except OSError: # the command is not available return False ovas_pid = result.pid logger.debug('pid = {0}'.format(ovas_pid)) openvas_db.item_add_single(('internal/ovas_pid'), [ ovas_pid, ]) # Wait until the scanner starts and loads all the preferences. while openvas_db.item_get_single('internal/' + openvas_scan_id) == 'new': time.sleep(1) no_id_found = False while True: time.sleep(3) # Check if the client stopped the whole scan if self.scan_is_stopped(openvas_scan_id): return 1 ctx = openvas_db.kb_connect(MAIN_KBINDEX) openvas_db.set_global_redisctx(ctx) dbs = openvas_db.item_get_set('internal/dbindex') for i in list(dbs): if i == MAIN_KBINDEX: continue ctx.execute_command('SELECT ' + str(i)) openvas_db.set_global_redisctx(ctx) id_aux = ctx.execute_command('srandmember internal/scan_id') if not id_aux: continue if id_aux == openvas_scan_id: no_id_found = False self.get_openvas_timestamp_scan_host(scan_id, target) self.get_openvas_result(scan_id) self.get_openvas_status(scan_id, target) if self.scan_is_finished(openvas_scan_id): ctx.execute_command('SELECT ' + str(MAIN_KBINDEX)) openvas_db.remove_set_member('internal/dbindex', i) openvas_db.release_db(i) # Scan end. No kb in use for this scan id if no_id_found: break no_id_found = True # Delete keys from KB related to this scan task. openvas_db.release_db(MAIN_KBINDEX) return 1