コード例 #1
0
    def _validate_module_params(self,
                                module_name,
                                profile_id,
                                module_args,
                                chaining_args=None):
        """
        A helper method to invoke module's validate_params method
        """
        if not module_args:
            raise CommandExecutionError(
                'Could not execute block \'{0}\', as it is not found.'.format(
                    profile_id))

        # Comparators must exist in Audit
        if self._caller == Caller.AUDIT:
            if 'args' not in module_args:
                raise HubbleCheckValidationError(
                    'No mention of args in audit-id: {0}'.format(profile_id))
            if 'comparator' not in module_args:
                raise HubbleCheckValidationError(
                    'No mention of comparator in audit-id: {0}'.format(
                        profile_id))
        elif self._caller == Caller.FDG:
            if 'module' not in module_args:
                raise CommandExecutionError(
                    'Could not execute block \'{0}\': no \'module\' found.'.
                    format(profile_id))
            acceptable_block_args = {
                'return',
                'module',
                'args',
                'comparator',
                'xpipe_on_true',
                'xpipe_on_false',
                'xpipe',
                'pipe',
                'pipe_on_true',
                'pipe_on_false',
            }
            for key in module_args:
                if key not in acceptable_block_args:
                    # Just doing error logging for unsupported tags
                    log.warning('Please check block \'{0}\': '
                                '\'{1}\' is an unsupported block key'.format(
                                    profile_id, key))
            if 'args' not in module_args and 'comparator' not in module_args:
                raise CommandExecutionError(
                    'Could not execute block \'{0}\': '
                    'either \'args\' or \'comparator\' is not present in block.'
                    .format(profile_id, key))

        validate_param_method = '{0}.validate_params'.format(module_name)
        __hmods__[validate_param_method](profile_id, module_args, {
            'chaining_args': chaining_args,
            'caller': self._caller
        })
コード例 #2
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': ['server1', 'server2'], 'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug(
        'Module: time_sync Start validating params for check-id: {0}'.format(
            block_id))

    ntp_servers = _get_ntp_servers(block_id, block_dict, extra_args)

    if not ntp_servers:
        raise HubbleCheckValidationError('No ntp_servers provided')

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #3
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': "True", 'status': True},
                  'caller': 'Audit'}
    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug('Module: bexpr Start validating params for check-id: {0}'.format(
        block_id))

    error = {}
    # check for calling module. Ony Audit is allowed.
    if extra_args.get('caller') == Caller.FDG:
        error['bexpr'] = 'Module: bexpr called from FDG !!!!'

    # fetch required param
    expr = runner_utils.get_param_for_module(block_id, block_dict, 'expr')
    if not expr:
        error[
            'expr'] = 'Mandatory parameter: expr not found for id: %s' % block_id

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #4
0
ファイル: number.py プロジェクト: umutbb/hubble
def _match(result_to_compare, expected_result):
    """
    compare a number
    """
    if isinstance(expected_result, int):
        return result_to_compare == expected_result

    result_to_compare = int(result_to_compare)
    # got string having some comparison operators
    expected_result_value = expected_result.strip()
    if expected_result_value.startswith('<='):
        return result_to_compare <= int(expected_result_value[2:].strip())
    elif expected_result_value.startswith('>='):
        return result_to_compare >= int(expected_result_value[2:].strip())
    elif expected_result_value.startswith('<'):
        return result_to_compare < int(expected_result_value[1:].strip())
    elif expected_result_value.startswith('>'):
        return result_to_compare > int(expected_result_value[1:].strip())
    elif expected_result_value.startswith('=='):
        return result_to_compare == int(expected_result_value[2:].strip())
    elif expected_result_value.startswith('!='):
        return result_to_compare != int(expected_result_value[2:].strip())
    else:
        raise HubbleCheckValidationError('Unknown operator in number::match arg: {0}'
                                         .format(expected_result_value))
コード例 #5
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': "/some/path/file.txt", 'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug('Module: pkg Start validating params for check-id: {0}'.format(
        block_id))

    error = {}
    name = runner_utils.get_chained_param(extra_args)
    if not name:
        name = runner_utils.get_param_for_module(block_id, block_dict, 'name')
    if not name:
        error['name'] = 'Mandatory parameter: name not found for id: %s' % (
            block_id)

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #6
0
ファイル: readfile.py プロジェクト: umutbb/hubble
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': '/some/path', 'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug(
        'Module: readfile Start validating params for check-id: {0}'.format(
            block_id))

    filepath = runner_utils.get_param_for_module(block_id, block_dict, 'path')
    file_format = runner_utils.get_param_for_module(block_id, block_dict,
                                                    'format')

    error = {}
    if not filepath:
        error['path'] = 'No filepath provided'
    if not file_format:
        error['format'] = 'No file format provided'

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #7
0
ファイル: osquery.py プロジェクト: umutbb/hubble
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': [{'name': 'CentOS Linux', 'platform': 'rhel', 'version': 'CentOS Linux release 7.8.2003 (Core)'}], 'status': True},
                  'caller': 'FDG'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug(
        'Module: osquery Start validating params for check-id: {0}'.format(
            block_id))

    query = runner_utils.get_param_for_module(block_id, block_dict, 'query')

    if not query:
        raise HubbleCheckValidationError(
            'Mandatory parameter: {0} not found for id: {1}'.format(
                'query', block_id))

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #8
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug('Module: curl Start validating params for check-id: {0}'.format(
        block_id))

    # fetch required param
    function_name = runner_utils.get_param_for_module(block_id, block_dict,
                                                      'function')
    if not function_name:
        function_name = 'GET'

    chain_error = {}
    chained_result = runner_utils.get_chained_param(extra_args)
    if chained_result:
        log.warning("Chained params are not supported in curl Module.")
        chain_error[
            'chained_params'] = "Chained params found in CURL module, returning with error"
        raise HubbleCheckValidationError(chain_error)

    url = runner_utils.get_param_for_module(block_id, block_dict, 'url')

    error = {}
    if function_name not in ('GET', 'PUT', 'POST'):
        error['function'] = 'Invalid request type: {0}'.format(function_name)

    if not url:
        error['url'] = 'URL not passed'

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #9
0
def execute(block_id, block_dict, extra_args=None):
    """
    Execute the module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': "/some/path/file.txt", 'status': True},
                  'caller': 'Audit'}

    returns:
        tuple of result(value) and status(boolean)
    """
    log.debug('Executing FDG Connector module for id: {0}'.format(block_id))

    fdg_file = runner_utils.get_chained_param(extra_args)
    if not fdg_file:
        fdg_file = runner_utils.get_param_for_module(block_id, block_dict,
                                                     'fdg_file')

    # read other params for fdg connector module
    starting_chained = runner_utils.get_param_for_module(
        block_id, block_dict, 'starting_chained')
    use_status = runner_utils.get_param_for_module(block_id, block_dict,
                                                   'use_status', False)
    consolidation_operator = runner_utils.get_param_for_module(
        block_id, block_dict, 'consolidation_operator', 'and')
    try:
        # fdg runner class
        fdg_runner = runner_factory.get_fdg_runner()
        fdg_runner.init_loader()

        # Handover to fdg_runner
        _, fdg_run = fdg_runner.execute(fdg_file,
                                        {'starting_chained': starting_chained})
    except Exception as e:
        raise HubbleCheckValidationError(
            'fdg_runner raised {0}: in file {1}, {2}'.format(
                e.__class__, fdg_file, e))

    if not isinstance(fdg_run, tuple):
        log.debug("consolidation_operator is %s", consolidation_operator)
        fdg_run = _get_consolidated_result(fdg_run, consolidation_operator)

    fdg_result, fdg_status = fdg_run
    if isinstance(fdg_result, dict) and 'error' in (k.lower()
                                                    for k in fdg_result):
        return runner_utils.prepare_negative_result_for_module(block_id, False)

    check_value = fdg_status if use_status else bool(fdg_result)
    if check_value:
        return runner_utils.prepare_positive_result_for_module(block_id, True)
    return runner_utils.prepare_negative_result_for_module(block_id, False)
コード例 #10
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': {'host_ip': '127.0.0.1',
                                                'host_port': 443},
                                    'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug(
        'Module: ssl_certificate Start validating params for check-id: {0}'.
        format(block_id))

    error = {}
    endpoint_chained = runner_utils.get_chained_param(extra_args)
    if endpoint_chained:
        host_ip = endpoint_chained.get('host_ip')
        host_port = endpoint_chained.get('host_port')
    else:
        host_ip = runner_utils.get_param_for_module(block_id, block_dict,
                                                    'host_ip')
        host_port = runner_utils.get_param_for_module(block_id, block_dict,
                                                      'host_port')

    ssl_timeout = runner_utils.get_param_for_module(block_id, block_dict,
                                                    'ssl_timeout', 0)
    path = runner_utils.get_param_for_module(block_id, block_dict, 'path')

    endpoint_present = bool(host_ip and host_port)
    if not endpoint_present and not path:
        error[
            'endpoint'] = 'Mandatory parameter: host_ip, host_port or path not found for id: %s' % (
                block_id)
    if endpoint_present and path:
        error[
            'endpoint'] = 'Only one of either endpoint data or path is required not both. Only one certificate per check for id: %s' % (
                block_id)

    if ssl_timeout < 0:
        error['ssl_timeout'] = 'Incorrect value provided for ssl_timeout'

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #11
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': "/some/path/file.txt", 'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug('Module: grep Start validating params for check-id: {0}'.format(
        block_id))

    error = {}
    filepath = None

    chaining_file_mode = runner_utils.get_param_for_module(
        block_id, block_dict, 'chain_filepath', False)
    if chaining_file_mode:
        # in chain_filepath mode, filepath from chaining is mandatory
        filepath = runner_utils.get_chained_param(extra_args)
        if not filepath:
            error[
                'path'] = 'Mandatory parameter: path not found for id: %s' % (
                    block_id)
    else:
        # fetch required param
        file_content = runner_utils.get_chained_param(extra_args)
        if not file_content:
            filepath = runner_utils.get_param_for_module(
                block_id, block_dict, 'path')
        if not file_content and not filepath:
            error[
                'path'] = 'Mandatory parameter: path not found for id: %s' % (
                    block_id)

    pattern_val = runner_utils.get_param_for_module(block_id, block_dict,
                                                    'pattern')
    if not pattern_val:
        error[
            'pattern'] = 'Mandatory parameter: pattern not found for id: %s' % (
                block_id)

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #12
0
ファイル: comparator.py プロジェクト: umutbb/hubble
def _find_comparator_command(args):
    """
    Find matched comparator's command
    """
    for comparator_key in args.keys():
        if comparator_key in ['type', 'success_on_error']:
            continue

        if 'type' not in args:
            raise HubbleCheckValidationError(
                'type keyword is not present in comparator')
        method_name = '{0}.{1}'.format(args['type'], comparator_key)
        if method_name in __comparator__:
            return method_name
    return None
コード例 #13
0
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': {'cmdline': 'app --config-file=test test'}, 'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug(
        'Module: command_line_parser Start validating params for check-id: {0}'
        .format(block_id))

    error = {}
    command_line = None
    chained_param = runner_utils.get_chained_param(extra_args)
    if chained_param:
        command_line = chained_param.get('cmdline')
    if not command_line:
        # get it from args
        command_line = runner_utils.get_param_for_module(
            block_id, block_dict, 'cmdline')

    if not command_line:
        error['cmdline'] = 'No cmdline provided in chained params'

    key_aliases = runner_utils.get_param_for_module(block_id, block_dict,
                                                    'key_aliases')
    if not key_aliases:
        error['key_aliases'] = 'No key_aliases provided in params'

    delimiter = runner_utils.get_param_for_module(block_id, block_dict,
                                                  'delimiter')
    if not delimiter:
        error['delimiter'] = 'No delimiter provided'

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #14
0
def validate_params(block_id, block_dict, extra_args=None):
    """
        Validate all mandatory params required for this module

        :param block_id:
            id of the block
        :param block_dict:
            parameter for this module
        :param extra_args:
            Chained argument dictionary, (If any)
            Example: {'chaining_args': {'result': {"name": "LogFileName", "value_type": "public"}, 'status': True},
                  'caller': 'Audit'}

        Raises:
            AuditCheckValidationError: For any validation error
        """
    log.debug(
        'Module: win_firewall. Start validating params for check-id: {0}'.
        format(block_id))

    error = {}

    # fetch required param
    chained_result = runner_utils.get_chained_param(extra_args)
    if chained_result:
        name = chained_result.get('name')
        value_type = chained_result.get('value_type')
    else:
        name = runner_utils.get_param_for_module(block_id, block_dict, 'name')
        value_type = runner_utils.get_param_for_module(block_id, block_dict,
                                                       'value_type')

    if not name:
        error[
            'name'] = 'Mandatory parameter: name not found for id: %s' % block_id
    if not value_type:
        error[
            'value_type'] = 'Mandatory parameter: value_type not found for id: %s' % block_id

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #15
0
def validate_params(block_id, block_dict, extra_args=None):
    r"""
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Chained argument dictionary, (If any)
        Example: {'chaining_args': {'result': "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\Application\MaxSize", 'status': True},
        'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug(
        "Module: win_reg. Start validating params for check-id: {0}".format(
            block_id))

    error = {}

    # fetch required param
    chained_pkg_name = None
    reg_name = None
    chained_result = runner_utils.get_chained_param(extra_args)
    if chained_result:
        chained_pkg_name = chained_result.get("name")
    else:
        reg_name = runner_utils.get_param_for_module(block_id, block_dict,
                                                     "name")
    if not chained_pkg_name and not reg_name:
        error[
            "name"] = "Mandatory parameter: name not found for id: %s" % block_id
    if error:
        raise HubbleCheckValidationError(error)

    log.debug("Validation success for check-id: {0}".format(block_id))
コード例 #16
0
ファイル: win_secedit.py プロジェクト: umutbb/hubble
def validate_params(block_id, block_dict, extra_args=None):
    """
        Validate all mandatory params required for this module

        :param block_id:
            id of the block
        :param block_dict:
            parameter for this module
        :param extra_args:
            Chained argument dictionary, (If any)
            Example: {'chaining_args': {'result': "SeRemoteInteractiveLogonRight", 'status': True},
                  'caller': 'Audit'}

        Raises:
            HubbleCheckValidationError: For any validation error
        """
    log.debug('Module: win_secedit. Start validating params for check-id: {0}'.
              format(block_id))

    error = {}

    # fetch required param
    chained_pkg_name = None
    sec_name = None
    chained_result = runner_utils.get_chained_param(extra_args)
    if chained_result:
        chained_pkg_name = chained_result.get("name")
    else:
        sec_name = runner_utils.get_param_for_module(block_id, block_dict,
                                                     'name')
    if not chained_pkg_name and not sec_name:
        error[
            'name'] = 'Mandatory parameter: name not found for id: %s' % block_id

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))
コード例 #17
0
    def _execute_audit(self, audit_id, audit_impl, audit_data, verbose, audit_profile, result_list=None):
        """
        Function to execute the module and return the result
        :param audit_id:
        :param audit_impl:
        :param audit_data:
        :param verbose:
        :param audit_profile:
        :return:
        """
        audit_result = {
            "check_unique_id": audit_id,
            "description": audit_data['description'],
            "audit_profile": audit_profile,
            "sub_check": audit_data.get('sub_check', False),
            "tag": audit_data['tag'],
            "check_id": audit_data['tag'],
            "module": audit_impl['module'],
            "run_config": {
                "filter": audit_impl['filter'],
            }
        }

        failure_reason = audit_data.get('failure_reason', '')
        invert_result = audit_data.get('invert_result', False)
        # check if the type of invert_result is boolean
        if not isinstance(invert_result, bool):
            raise HubbleCheckValidationError('value of invert_result is not a boolean in audit_id: {0}'.format(audit_id))

        return_no_exec = audit_impl.get('return_no_exec', False)
        # check if the type of invert_result is boolean
        if not isinstance(return_no_exec, bool):
            raise HubbleCheckValidationError('value of return_no_exec is not a boolean in audit_id: {0}'.format(audit_id))
        check_eval_logic = audit_impl.get('check_eval_logic', 'and')
        if check_eval_logic:
            check_eval_logic = check_eval_logic.lower().strip()

        # check for check_eval_logic in check implementation. If not present default is 'and'
        audit_result['run_config']['check_eval_logic'] = check_eval_logic
        audit_result['invert_result'] = invert_result

        # check if return_no_exec is true
        if return_no_exec:
            audit_result['run_config']['return_no_exec'] = True
            check_result = CHECK_STATUS['Success']
            if invert_result:
                check_result = CHECK_STATUS['Failure']
                audit_result['failure_reason'] = failure_reason
            audit_result['check_result'] = check_result
            return audit_result

        # Check presence of implementation checks
        if 'items' not in audit_impl:
            raise HubbleCheckValidationError('No checks are present in audit_id: {0}'.format(audit_id))
        if check_eval_logic not in ['and', 'or']:
            raise HubbleCheckValidationError(
                "Incorrect value provided for parameter 'check_eval_logic': %s" % check_eval_logic)

        # Execute module validation of params
        for audit_check in audit_impl['items']:
            self._validate_module_params(audit_impl['module'], audit_id, audit_check)

        # validate succeeded, lets execute it and prepare result dictionary
        audit_result['run_config']['items'] = []

        # calculate the check result based on check_eval_logic parameter.
        # If check_eval_logic is 'and', all subchecks should pass for success.
        # If check_eval_logic is 'or', any passed subcheck will result in success.
        overall_result = check_eval_logic == 'and'
        failure_reasons = []
        for audit_check in audit_impl['items']:
            mod_status, module_result_local = self._execute_module(audit_impl['module'], audit_id, audit_check,
                                                                   extra_args=result_list)
            # Invoke Comparator
            comparator_status, comparator_result = hubblestack.module_runner.comparator.run(
                audit_id, audit_check['comparator'], module_result_local, mod_status)

            audit_result_local = {}
            if comparator_status:
                audit_result_local['check_result'] = CHECK_STATUS['Success']
            else:
                audit_result_local['check_result'] = CHECK_STATUS['Failure']
                audit_result_local['failure_reason'] = comparator_result if comparator_result else module_result_local[
                    'error']
                module_failure_reason = self._get_module_failure_reason(audit_impl['module'], audit_id, audit_check)
                failure_reasons.append(audit_result_local['failure_reason'])
                failure_reasons.append(module_failure_reason)
            module_logs = {}
            if not verbose:
                log.debug('Non verbose mode')
                module_logs = self._get_filtered_params_to_log(audit_impl['module'], audit_id, audit_check)
                if not module_logs:
                    module_logs = {}
            else:
                log.debug('verbose mode')
                module_logs = audit_check

            audit_result_local = {**audit_result_local, **module_logs}
            # add this result
            audit_result['run_config']['items'].append(audit_result_local)

            if check_eval_logic == 'and':
                overall_result = overall_result and comparator_status
            else:
                overall_result = overall_result or comparator_status

        # Update overall check result based on invert result
        if invert_result:
            log.debug("Inverting result for check: %s as invert_result is set to True" % audit_id)
            overall_result = not overall_result

        if overall_result:
            audit_result['check_result'] = CHECK_STATUS['Success']
        else:
            audit_result['check_result'] = CHECK_STATUS['Failure']
            # fetch failure reason. If it is not present in profile, combine all individual checks reasons.
            if failure_reason:
                audit_result['failure_reason'] = failure_reason
            else:
                if failure_reasons:
                    failure_reasons = set(failure_reasons)
                    audit_result['failure_reason'] = ', '.join(failure_reasons)
        return audit_result
コード例 #18
0
def execute(block_id, block_dict, extra_args=None):
    """
    Execute the module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': "True", 'status': True},
                  'extra_args': [{'check_id': 'ADOBE-01',
                                  'check_status': 'Success'}]
                  'caller': 'Audit'}

    returns:
        tuple of result(value) and status(boolean)
    """
    log.debug('Executing bexpr module for check-id: %s' % block_id)
    result_list = extra_args.get('extra_args')
    keyword_list = ['AND', 'OR', 'NOT', '(', ')']
    operand_list = ['AND', 'OR', 'NOT']
    expression = runner_utils.get_param_for_module(block_id, block_dict,
                                                   'expr')
    original_expression = expression
    # Separating keywords on the basis of space
    expression = expression.replace('(', ' ( ')
    expression = expression.replace(')', ' ) ')
    # Parse the expression and evaluate the result
    # Splitting the expression on the basis of spaces
    expr_list = expression.split(" ")
    # Filtering out empty spaces
    expr_list = list(filter(None, expr_list))
    referred_checks_list = []
    referred_checks_result = {}
    operand_present = 0
    for expr in expr_list:
        if expr.upper() not in keyword_list:
            referred_checks_list.append(expr)
        elif expr.upper() in operand_list:
            operand_present += 1
    # Fetch the result of check from result list and store the result of referenced checks
    # In case a check is not present in result list or referred check result is not Success or Failure, raise an Error
    error = {}
    if len(referred_checks_list) == 0:
        error[
            block_id] = "No checks are referred in the boolean expression: %s" % original_expression
    if len(referred_checks_list) > 1 and operand_present == 0:
        error[
            block_id] = "No operand is present for multiple referred checks in boolean expression: %s" % original_expression

    if error:
        raise HubbleCheckValidationError(error)

    for referred_check_id in referred_checks_list:
        check_found = False
        for result in result_list:
            if result.get('check_unique_id', '') == referred_check_id:
                check_found = True
                check_result = result.get('check_result', '')
                if check_result == "Success":
                    referred_checks_result[referred_check_id] = "True"
                elif check_result == "Failure":
                    referred_checks_result[referred_check_id] = "False"
                else:
                    error[
                        block_id] = "Referred check: %s result is %s. Setting boolean expression check result to error." % (
                            referred_check_id, check_result)
                break

    if not check_found:
        error[
            block_id] = "Referred check: %s is not available. Please verify correct check is referred." % (
                referred_check_id)
    if error:
        raise HubbleCheckValidationError(error)

    try:
        check_result = _evaluate_expression(expr_list, keyword_list,
                                            referred_checks_result)
    except Exception as e:
        error[
            block_id] = "Error in evaluating boolean expression: %s Please verify the expression" % original_expression
        raise HubbleCheckValidationError(error)

    if not bool(check_result):
        log.info("Boolean expression: '%s' evaluated to failure" %
                 original_expression)
        return runner_utils.prepare_positive_result_for_module(block_id, False)

    return runner_utils.prepare_positive_result_for_module(block_id, True)
コード例 #19
0
ファイル: util.py プロジェクト: umutbb/hubble
def validate_params(block_id, block_dict, extra_args=None):
    """
    Validate all mandatory params required for this module

    :param block_id:
        id of the block
    :param block_dict:
        parameter for this module
    :param extra_args:
        Extra argument dictionary, (If any)
        Example: {'chaining_args': {'result': "Output (can be string/dict/list)", 'status': True},
                  'caller': 'Audit'}

    Raises:
        HubbleCheckValidationError: For any validation error
    """
    log.debug('Module: util Start validating params for check-id: {0}'.format(
        block_id))

    # fetch required param
    error = {}

    # This module is callable from FDG only
    if extra_args.get('caller') == Caller.AUDIT:
        error['util'] = 'Module: util called from AUDIT !!!!'

    function_param = runner_utils.get_param_for_module(block_id, block_dict,
                                                       'function')
    if not function_param:
        error[
            'function'] = 'Mandatory parameter: function not found for id: %s' % (
                block_id)
    elif function_param not in [
            'filter_dict', 'filter_seq', 'get_index', 'get_key', 'join',
            'dict_to_list', 'dict_convert_none', 'print_string',
            'dict_remove_none', 'nop', 'encode_base64'
    ]:
        error['function'] = 'Unsupported function in util: {0}'.format(
            function_param)
    else:
        if function_param == 'filter_dict':
            if not runner_utils.get_param_for_module(block_id, block_dict,
                                                     'filter_rules'):
                error[
                    'filter_rules'] = 'filter_rules required for function: filter_dict'
        elif function_param == 'filter_seq':
            if not runner_utils.get_param_for_module(block_id, block_dict,
                                                     'filter_rules'):
                error[
                    'filter_rules'] = 'filter_rules required for function: filter_seq'
        elif function_param == 'get_key':
            if not runner_utils.get_param_for_module(block_id, block_dict,
                                                     'key'):
                error['key'] = 'key is required for function: get_key'
        elif function_param == 'join':
            if not runner_utils.get_param_for_module(block_id, block_dict,
                                                     'words'):
                error['words'] = 'words are required for function: join'
        elif function_param == [
                'dict_convert_none', 'print_string', 'dict_to_list',
                'get_index', 'dict_remove_none', 'nop', 'encode_base64'
        ]:
            # no mandatory key, mentioned here just for clarity
            pass

    if error:
        raise HubbleCheckValidationError(error)

    log.debug('Validation success for check-id: {0}'.format(block_id))