Esempio n. 1
0
    def _set_nvti_cache_name(self):
        """Set nvticache name"""
        version_string = Openvas.get_gvm_libs_version()
        if not version_string:
            raise OspdOpenvasError(
                "Not possible to get the installed gvm-libs version. "
                "Outdated openvas version. openvas version needs to be at "
                "least 7.0.1.")
        # Remove pre-release sufix and git revision if exists
        # as the gvm-libs version has the  format
        # e.g "20.8+beta1-git-a41b140d-zero-padding"
        version_string = version_string.split("+")[0]

        if self._is_compatible_version(version_string):
            self._nvti_cache_name = "nvticache{}".format(version_string)
        else:
            raise OspdOpenvasError(
                "Error setting nvticache. Incompatible nvticache "
                "version {}. Supported versions are {}.".format(
                    version_string,
                    ", ".join([
                        str(spec)
                        for spec in SUPPORTED_NVTICACHE_VERSIONS_SPECIFIER
                    ]),
                ))
Esempio n. 2
0
    def _set_nvti_cache_name(self):
        """Set nvticache name"""
        version_string = Openvas.get_gvm_libs_version()
        if not version_string:
            raise OspdOpenvasError(
                "Not possible to get the installed gvm-libs version. "
                "Outdated openvas version. openvas version needs to be at "
                "least 7.0.1."
            )

        if self._is_compatible_version(version_string):
            self._nvti_cache_name = "nvticache{}".format(version_string)
        else:
            raise OspdOpenvasError(
                "Error setting nvticache. Incompatible nvticache "
                "version {}. Supported versions are {}.".format(
                    version_string,
                    ", ".join(
                        [
                            str(spec)
                            for spec in SUPPORTED_NVTICACHE_VERSIONS_SPECIFIER
                        ]
                    ),
                )
            )
Esempio n. 3
0
    def feed_is_outdated(self, current_feed):
        """ Compare the current feed with the one in the disk.

        Return:
            False if there is no new feed.
            True if the feed version in disk is newer than the feed in
            redis cache.
            None if there is no feed
            the disk.
        """
        plugins_folder = self.scan_only_params.get('plugins_folder')
        if not plugins_folder:
            raise OspdOpenvasError("Error: Path to plugins folder not found.")

        feed_info_file = Path(plugins_folder) / 'plugin_feed_info.inc'
        if not feed_info_file.exists():
            self.parse_param()
            msg = 'Plugins feed file %s not found.' % feed_info_file
            logger.debug(msg)
            return None

        date = 0
        with open(str(feed_info_file)) as fcontent:
            for line in fcontent:
                if "PLUGIN_SET" in line:
                    date = line.split(' = ')[1]
                    date = date.replace(';', '')
                    date = date.replace('"', '')
        if int(current_feed) < int(date) or int(date) == 0:
            return True
        return False
Esempio n. 4
0
    def get_feed_info(self) -> Dict[str, Any]:
        """Parses the current plugin_feed_info.inc file"""

        plugins_folder = self.scan_only_params.get('plugins_folder')
        if not plugins_folder:
            raise OspdOpenvasError("Error: Path to plugins folder not found.")

        feed_info_file = Path(plugins_folder) / 'plugin_feed_info.inc'
        if not feed_info_file.exists():
            self.set_params_from_openvas_settings()
            logger.debug('Plugins feed file %s not found.', feed_info_file)
            return {}

        feed_info = {}
        with feed_info_file.open(encoding='utf-8') as fcontent:
            for line in fcontent:

                try:
                    key, value = line.split('=', 1)
                except ValueError:
                    continue
                key = key.strip()
                value = value.strip()
                value = value.replace(';', '')
                value = value.replace('"', '')
                if value:
                    feed_info[key] = value

        return feed_info
Esempio n. 5
0
    def nvti(self) -> NVTICache:
        if self._nvti is None:
            try:
                maindb = MainDB()
                self._nvti = NVTICache(maindb)
            except SystemExit:
                raise OspdOpenvasError(
                    "Could not connect to the Redis KB") from None

        return self._nvti
Esempio n. 6
0
    def add_vt_to_cache(self, vt_id: str, vt: List[str]):
        if not vt_id:
            raise RequiredArgument('add_vt_to_cache', 'vt_id')
        if not vt:
            raise RequiredArgument('add_vt_to_cache', 'vt')
        if not isinstance(vt, list) or len(vt) != 15:
            raise OspdOpenvasError('Error trying to load the VT'
                                   ' {} in cache'.format(vt))

        OpenvasDB.add_single_list(self.ctx, vt_id, vt)
Esempio n. 7
0
    def max_db_index(self):
        """Set the number of databases have been configured into kbr struct.
        """
        ctx = self.kb_connect()
        resp = ctx.config_get('databases')

        if len(resp) == 1:
            self.max_dbindex = int(resp.get('databases'))
        else:
            raise OspdOpenvasError(
                'Redis Error: Not possible to get max_dbindex.')
Esempio n. 8
0
    def _get_gvm_libs_version_string(self) -> str:
        """ Parse version of gvm-libs
        """
        try:
            result = subprocess.check_output(['openvas', '--version'], )
        except (CalledProcessError, PermissionError) as e:
            raise OspdOpenvasError(
                "Not possible to get the installed gvm-libs version. %s" % e)

        output = result.decode('utf-8').rstrip()

        if 'gvm-libs' not in output:
            raise OspdOpenvasError(
                "Not possible to get the installed gvm-libs version. "
                "Outdated openvas version. openvas version needs to be at "
                "least 7.0.1.")

        lines = output.splitlines()
        _, version_string = lines[1].split(' ', 1)
        return version_string
Esempio n. 9
0
    def max_database_index(self):
        """Set the number of databases have been configured into kbr struct."""
        if self._max_dbindex is None:
            resp = self.ctx.config_get('databases')

            if len(resp) == 1:
                self._max_dbindex = int(resp.get('databases'))
            else:
                raise OspdOpenvasError(
                    'Redis Error: Not possible to get max_dbindex.') from None

        return self._max_dbindex
Esempio n. 10
0
    def add_vt_to_cache(self, vt_id: str, vt: List[str]):
        if not vt_id:
            raise RequiredArgument('add_vt_to_cache', 'vt_id')
        if not vt:
            raise RequiredArgument('add_vt_to_cache', 'vt')
        if not isinstance(vt, list) or len(vt) != 15:
            raise OspdOpenvasError(
                f'Error trying to load the VT {vt} in cache')

        OpenvasDB.add_single_list(self.ctx, vt_id, vt)

        OpenvasDB.add_single_item(self.ctx, f'filename:{vt[0]}', [int(time())])
Esempio n. 11
0
    def get_kb_context(self) -> RedisCtx:
        """ Get redis context if it is already connected or do a connection.
        """
        if self.rediscontext is not None:
            return self.rediscontext

        self.rediscontext = self.db_find(self.DBINDEX_NAME)

        if self.rediscontext is None:
            raise OspdOpenvasError(
                'Redis Error: Problem retrieving Redis Context')

        return self.rediscontext
Esempio n. 12
0
    def _set_nvti_cache_name(self):
        """Set nvticache name"""
        version_string = self._get_gvm_libs_version_string()

        if self._is_compatible_version(version_string):
            self._nvti_cache_name = "nvticache{}".format(version_string)
        else:
            raise OspdOpenvasError(
                "Error setting nvticache. Incompatible nvticache "
                "version {}. Supported versions are {}.".format(
                    version_string,
                    ", ".join([
                        str(spec)
                        for spec in SUPPORTED_NVTICACHE_VERSIONS_SPECIFIER
                    ]),
                ))
Esempio n. 13
0
    def get_db_connection(self):
        """ Retrieve the db address from openvas config.
        """
        if self.db_address:
            return
        try:
            result = subprocess.check_output(['openvas', '-s'],
                                             stderr=subprocess.STDOUT)
        except (PermissionError, OSError, subprocess.CalledProcessError) as e:
            raise OspdOpenvasError(
                "{}: Not possible to run openvas. {}".format(
                    self.get_db_connection.__name__, e))

        if result:
            path = self._parse_openvas_db_address(result)

        self.db_address = path
Esempio n. 14
0
    def _parse_openvas_db_address(result: bytes) -> str:
        """ Return the path to the redis socket.
        Arguments:
            result: Output of `openvas -s`
        Return redis unix socket path.
        """
        path = None
        result = result.decode('ascii')
        for conf in result.split('\n'):
            if conf.find('db_address') == 0:
                path = conf.split('=')
                break

        if not path:
            raise OspdOpenvasError('Redis Error: Not possible to '
                                   'find the path to the redis socket.')
        return path[1].strip()
Esempio n. 15
0
    def feed_is_outdated(self, current_feed: str) -> Optional[bool]:
        """Compare the current feed with the one in the disk.

        Return:
            False if there is no new feed.
            True if the feed version in disk is newer than the feed in
                redis cache.
            None if there is no feed on the disk.
        """
        plugins_folder = self.scan_only_params.get('plugins_folder')
        if not plugins_folder:
            raise OspdOpenvasError("Error: Path to plugins folder not found.")

        feed_info_file = Path(plugins_folder) / 'plugin_feed_info.inc'
        if not feed_info_file.exists():
            self.set_params_from_openvas_settings()
            logger.debug('Plugins feed file %s not found.', feed_info_file)
            return None

        current_feed = safe_int(current_feed)
        if current_feed is None:
            logger.debug(
                "Wrong PLUGIN_SET format in plugins feed file %s. Format has to"
                " be yyyymmddhhmm. For example 'PLUGIN_SET = \"201910251033\"'",
                feed_info_file,
            )

        feed_date = None
        with feed_info_file.open() as fcontent:
            for line in fcontent:
                if "PLUGIN_SET" in line:
                    feed_date = line.split('=', 1)[1]
                    feed_date = feed_date.strip()
                    feed_date = feed_date.replace(';', '')
                    feed_date = feed_date.replace('"', '')
                    feed_date = safe_int(feed_date)
                    break

        logger.debug("Current feed version: %s", current_feed)
        logger.debug("Plugin feed version: %s", feed_date)

        return (
            (not feed_date) or (not current_feed) or (current_feed < feed_date)
        )
Esempio n. 16
0
    def try_database(self, index: int) -> bool:
        """ Check if a redis db is already in use. If not, set it
        as in use and return.

        Arguments:
            ctx: Redis object connected to the kb with the
                DBINDEX_NAME key.
            index: Number intended to be used.

        Return True if it is possible to use the db. False if the given db
            number is already in use.
        """
        _in_use = 1
        try:
            resp = self.ctx.hsetnx(DBINDEX_NAME, index, _in_use)
        except:
            raise OspdOpenvasError('Redis Error: Not possible to set %s.' %
                                   DBINDEX_NAME)

        return resp == 1
Esempio n. 17
0
    def try_database_index(self, ctx: RedisCtx, kb: int) -> bool:
        """ Check if a redis kb is already in use. If not, set it
        as in use and return.
        Arguments:
            ctx: Redis object connected to the kb with the
                DBINDEX_NAME key.
            kb: Kb number intended to be used.

        Return True if it is possible to use the kb. False if the given kb
            number is already in use.
        """
        _in_use = 1
        try:
            resp = ctx.hsetnx(self.DBINDEX_NAME, kb, _in_use)
        except:
            raise OspdOpenvasError('Redis Error: Not possible to set %s.' %
                                   self.DBINDEX_NAME)

        if resp == 1:
            return True
        return False
Esempio n. 18
0
    def kb_connect(self, dbnum=0):
        """ Connect to redis to the given database or to the default db 0 .

        Arguments:
            dbnum (int, optional): The db number to connect to.

        Return a redis context on success.
        """
        self.get_db_connection()
        tries = 5
        while tries:
            try:
                ctx = redis.Redis(
                    unix_socket_path=self.db_address,
                    db=dbnum,
                    socket_timeout=SOCKET_TIMEOUT,
                    encoding="latin-1",
                    decode_responses=True,
                )
                ctx.keys("test")
            except (redis.exceptions.ConnectionError,
                    FileNotFoundError) as err:
                logger.debug(
                    'Redis connection lost: %s. Trying again in 5 seconds.',
                    err)
                tries = tries - 1
                time.sleep(5)
                continue
            break

        if not tries:
            raise OspdOpenvasError(
                'Redis Error: Not possible to connect to the kb.')

        self.db_index = dbnum
        return ctx