Esempio n. 1
0
    async def start(self):
        """ Start up the job queue including resource initialisation. """
        awaitables = []
        for worker in self.workers:
            awaitables.append(await worker.start())

        if self.cluster_duplicate_handler:
            awaitables.append(await self.cluster_duplicate_handler.start())

        # create a single ruleset engine for all workers, instantiates all the
        # rules based on the ruleset configuration, may start up long-lived
        # analyzer instances which are shared as well, is otherwise stateless
        # to allow concurrent use by multiple worker
        try:
            awaitables.extend(await self.ruleset_engine.start())
        except (KeyError, ValueError, PeekabooConfigException) as error:
            self.shut_down()
            await self.close_down()
            raise PeekabooConfigException('Ruleset configuration error: %s' %
                                          error)
        except PeekabooRulesetConfigError as error:
            self.shut_down()
            await self.close_down()
            raise PeekabooConfigException(error)

        return awaitables
Esempio n. 2
0
    def __init__(self, config_file):
        super().__init__(interpolation=ListInterpolation())

        # interpolation calls our add_list_value() from read_file() and read()
        # which needs these defined
        self.lists = {}
        self.relists = {}

        try:
            self.read_file(open(config_file))
        except IOError as ioerror:
            raise PeekabooConfigException(
                'Configuration file "%s" can not be opened for reading: %s' %
                (config_file, ioerror))
        except configparser.Error as cperror:
            raise PeekabooConfigException(
                'Configuration file "%s" can not be parsed: %s' %
                (config_file, cperror))

        # main configuration file may contain options in global section that
        # configure drop-file read behaviour
        drop_dir_template = self.get('global',
                                     'drop_dir_template',
                                     fallback='{config_path}.d')
        drop_file_glob = self.get('global',
                                  'drop_file_glob',
                                  fallback='[0-9][0-9]-*.conf')

        config_dir = os.path.dirname(config_file)
        config_basename = os.path.basename(config_file)

        drop_dir = drop_dir_template.format(config_path=config_file,
                                            config_dir=config_dir,
                                            config_file=config_basename)

        drop_files = sorted(glob.glob(os.path.join(drop_dir, drop_file_glob)))

        try:
            read_files = self.read(drop_files)
        except configparser.Error as cperror:
            raise PeekabooConfigException(
                f'Configuration drop file can not be parsed: {cperror}'
            ) from cperror

        missing_files = set(drop_files) - set(read_files)
        if missing_files:
            raise PeekabooConfigException(
                'Some configuration drop files could not be read: '
                f'{missing_files}')
Esempio n. 3
0
    def get_log_level(self,
                      section,
                      option,
                      raw=False,
                      vars=None,
                      fallback=None):
        """ Get the log level from the configuration file and parse the string
        into a logging loglevel such as logging.CRITICAL. Raises config
        exception if the log level is unknown. Options identical to get(). """
        levels = {
            'CRITICAL': logging.CRITICAL,
            'ERROR': logging.ERROR,
            'WARNING': logging.WARNING,
            'INFO': logging.INFO,
            'DEBUG': logging.DEBUG
        }

        level = self.get(section, option, raw=raw, vars=vars, fallback=None)
        if level is None:
            return fallback

        if level not in levels:
            raise PeekabooConfigException('Unknown log level %s' % level)

        return levels[level]
Esempio n. 4
0
    def __init__(self, config_file):
        super().__init__()

        try:
            self.read_file(open(config_file))
        except IOError as ioerror:
            raise PeekabooConfigException(
                'Configuration file "%s" can not be opened for reading: %s' %
                (config_file, ioerror))
        except configparser.Error as cperror:
            raise PeekabooConfigException(
                'Configuration file "%s" can not be parsed: %s' %
                (config_file, cperror))

        self.lists = {}
        self.relists = {}
Esempio n. 5
0
    def __init__(self, config_file):
        # super() does not work here because ConfigParser uses old-style
        # classes in python 2
        configparser.ConfigParser.__init__(self)

        try:
            self.read_file(open(config_file))
        except IOError as ioerror:
            raise PeekabooConfigException(
                'Configuration file "%s" can not be opened for reading: %s' %
                (config_file, ioerror))
        except configparser.Error as cperror:
            raise PeekabooConfigException(
                'Configuration file "%s" can not be parsed: %s' %
                (config_file, cperror))

        self.lists = {}
        self.relists = {}
Esempio n. 6
0
    def getlist(self, section, option, raw=False, vars=None, fallback=None):
        """ Special getter where multiple options in the config file
        distinguished by a .<no> suffix form a list. Matches the signature for
        configparser getters. """
        # cache results because the following is somewhat inefficient
        if section not in self.lists:
            self.lists[section] = {}

        if option in self.lists[section]:
            return self.lists[section][option]

        if section not in self:
            self.lists[section][option] = fallback
            return fallback

        # Go over all options in this section we want to allow "holes" in
        # the lists, i.e setting.1, setting.2 but no setting.3 followed by
        # setting.4. We use here that ConfigParser retains option order from
        # the file.
        value = []
        for setting in self[section]:
            if not setting.startswith(option):
                continue

            # Parse 'setting' into (key) and 'setting.subscript' into
            # (key, subscript) and use it to determine if this setting is a
            # list. Note how we do not use the subscript at all here.
            name_parts = setting.split('.')
            key = name_parts[0]
            is_list = len(name_parts) > 1

            if key != option:
                continue

            if not is_list:
                raise PeekabooConfigException(
                    'Option %s in section %s is supposed to be a list '
                    'but given as individual setting' % (setting, section))

            # Potential further checks:
            # - There are no duplicate settings with ConfigParser. The last
            #   one always wins.

            value.append(self[section].get(setting, raw=raw, vars=vars))

        # it's not gonna get any better on the next call, so cache even the
        # default
        if not value:
            value = fallback

        self.lists[section][option] = value
        return value
Esempio n. 7
0
    def getlist(self, section, option, raw=False, vars=None, fallback=None):
        """ Special getter where multiple options in the config file
        distinguished by a .<no> suffix form a list. Matches the signature for
        configparser getters. """
        if section in self and option in self[section]:
            raise PeekabooConfigException(
                f'Option {option} in section {section} is supposed to be a '
                'list but given as individual setting')

        if section in self.lists and option in self.lists[section]:
            return self.lists[section][option]

        return fallback
Esempio n. 8
0
    def check_sections(self, known_sections):
        """ Check a list of known section names against this configuration

        @param known_sections: names of known sections
        @type known_sections: list(string)

        @returns: None
        @raises PeekabooConfigException: if any unknown sections are found in
                                         the configuration.
        """
        section_diff = set(self.sections()) - set(known_sections)
        if section_diff:
            raise PeekabooConfigException(
                'Unknown section(s) found in config: %s' %
                ', '.join(section_diff))
Esempio n. 9
0
    def getoctal(self, section, option, raw=False, vars=None, fallback=None):
        """ Get an integer in octal notation. Raises config
        exception if the format is wrong. Options identical to get(). """
        value = self.get(section, option, raw=raw, vars=vars, fallback=None)
        if value is None:
            return fallback

        try:
            octal = int(value, 8)
        except ValueError:
            raise PeekabooConfigException(
                'Invalid value for octal option %s in section %s: %s' %
                (option, section, value))

        return octal
Esempio n. 10
0
    def getrelist(self,
                  section,
                  option,
                  raw=False,
                  vars=None,
                  fallback=None,
                  flags=0):
        """ Special getter for lists of regular expressions. Returns the
        compiled expression objects in a list ready for matching and searching.
        """
        if section not in self.relists:
            self.relists[section] = {}

        if option in self.relists[section]:
            return self.relists[section][option]

        if section not in self:
            self.relists[section][option] = fallback
            return fallback

        strlist = self[section].getlist(option,
                                        raw=raw,
                                        vars=vars,
                                        fallback=fallback)
        if strlist is None:
            self.relists[section][option] = None
            return None

        compiled_res = []
        for regex in strlist:
            try:
                compiled_res.append(re.compile(regex, flags))
            except (ValueError, TypeError) as error:
                raise PeekabooConfigException(
                    'Failed to compile regular expression "%s" (section %s, '
                    'option %s): %s' % (re, section, option, error))

        # it's not gonna get any better on the next call, so cache even the
        # default
        if not compiled_res:
            compiled_res = fallback

        self.relists[section][option] = compiled_res
        return compiled_res
Esempio n. 11
0
    def gettlp(self, section, option, raw=False, vars=None, fallback=None):
        levels = {
            'red': tlp.RED,
            '3': tlp.RED,
            'amber': tlp.AMBER,
            '2': tlp.AMBER,
            'green': tlp.GREEN,
            '1': tlp.GREEN,
            'white': tlp.WHITE,
            '0': tlp.WHITE,
        }

        level = self.get(section, option, raw=raw, vars=vars, fallback=None)
        if level is None:
            return fallback
        level = level.lower()

        if level not in levels:
            raise PeekabooConfigException('Unknown tlp level %s' % level)

        return levels[level]
Esempio n. 12
0
    def check_section_options(self, section, known_options):
        """ Check a config section for unknown options.

        @param section: name of section to check
        @type section: string
        @param known_options: list of names of known options to check against
        @type known_options: list(string)

        @returns: None
        @raises PeekabooConfigException: if any unknown options are found. """
        try:
            section_options = map(
                # account for option.1 list syntax
                lambda x: x.split('.')[0],
                self.options(section))
        except configparser.NoSectionError:
            # a non-existant section can have no non-allowed options :)
            return

        option_diff = set(section_options) - set(known_options)
        if option_diff:
            raise PeekabooConfigException(
                'Unknown config option(s) found in section %s: %s' %
                (section, ', '.join(option_diff)))