Example #1
0
    def get_alert_profile(service_name, service_config):
        alert_profile = safe_get(service_config, 'alertProfile', str)

        if not alert_profile:
            raise BackendError(
                f'Lacework backend could not determine alert profile for service {service_name}')

        return alert_profile
Example #2
0
    def get_query_returns(service_name, service_config):
        returns = safe_get(service_config, 'returns', list)

        if not returns:
            raise BackendError(
                f'Lacework backend could not determine returns for service {service_name}')

        return returns
Example #3
0
    def get_query_source(service_name, service_config):
        # 4. validate service has a source mapping
        source = safe_get(service_config, 'source', str)

        if not source:
            raise BackendError(
                f'Lacework backend could not determine source for service {service_name}')

        return source
Example #4
0
    def get_evaluator_id(service_name, service_config):
        # 3. validate service has an evaluatorId mapping
        evaluator_id = safe_get(service_config, 'evaluatorId', str)

        if not evaluator_id:
            raise BackendError(
                f'Lacework backend could not determine evaluatorId for service {service_name}')

        return evaluator_id
Example #5
0
    def generateMapItemNode(self, node):
        """
        Map Expression for Lacework Query Language (LQL)

        Special handling for contains by inspecting value for wildcards
        """
        fieldname, value = node

        if self._should_ignore_field(fieldname):
            return None
        transformed_fieldname = self.fieldNameMapping(fieldname, value)

        # is not null
        if value == '*':
            if ':' in transformed_fieldname:
                return f'value_exists({transformed_fieldname})'
            return f'{transformed_fieldname} is not null'
        # contains
        if (isinstance(value, str) and value.startswith('*')
                and value.endswith('*')):
            value = self.generateValueNode(value[1:-1])
            return f"contains({transformed_fieldname}, {value})"
        # startswith
        if (isinstance(value, str) and value.endswith(
                '*')  # a wildcard at the end signifies startswith
            ):
            value = self.generateValueNode(value[:-1])
            return f"starts_with({transformed_fieldname}, {value})"
        # endswith
        if (isinstance(value, str) and value.startswith(
                '*')  # a wildcard at the start signifies endswith
            ):
            value = f'%{value[1:]}'
            new_value = self.generateValueNode(value)
            if new_value != (self.valueExpression % value):
                raise BackendError(
                    'Lacework backend only supports endswith for literal string values'
                )
            return f"{transformed_fieldname} LIKE {new_value}"
        if isinstance(value, (str, int)):
            return self.mapExpression % (transformed_fieldname,
                                         self.generateNode(value))
        # mapListsHandling
        elif type(value) == list:
            # if a list contains values with wildcards we can't use standard handling ("in")
            if any([x for x in value if x.startswith('*') or x.endswith('*')]):
                node = NodeSubexpression(
                    ConditionOR(None, None,
                                *[(transformed_fieldname, x) for x in value]))
                return self.generateNode(node)
            return self.generateMapItemListNode(transformed_fieldname, value)
        elif value is None:
            return self.nullExpression % (transformed_fieldname, )
        else:
            raise TypeError(
                f'Lacework backend does not support map values of type {type(value)}'
            )
Example #6
0
    def get_service_config(config, service):
        config = safe_get(config, 'services', dict)
        service_config = safe_get(config, service, dict)

        # 1. validate logsource service
        if not service_config:
            raise BackendError(
                f'Service {service} is not supported by the Lacework backend')

        return service_config
Example #7
0
    def get_logsource_config(config, logsource_type, logsource_name):
        config = safe_get(config, logsource_type, dict)
        logsource_config = safe_get(config, logsource_name, dict)

        # 1. validate logsource service
        if not logsource_config:
            raise BackendError(
                f'Log source {logsource_name} is not supported by the Lacework backend'
            )

        return logsource_config
Example #8
0
    def generateMapItemNode(self, node):
        """
        Map Expression for Lacework Query Language (LQL)

        Special handling for contains by inspecting value for wildcards
        """
        fieldname, value = node

        transformed_fieldname = self.fieldNameMapping(fieldname, value)

        # is not null
        if value == '*':
            return f'{transformed_fieldname} is not null'
        # contains
        if (
            isinstance(value, str)
            and value.startswith('*')
            and value.endswith('*')
        ):
            value = self.generateValueNode(value[1:-1])
            return f"contains({transformed_fieldname}, {value})"
        # startswith
        if (
            isinstance(value, str)
            and value.endswith('*')  # a wildcard at the end signifies startswith
        ):
            value = self.generateValueNode(value[:-1])
            return f"starts_with({transformed_fieldname}, {value})"
        # endswith
        if (
            isinstance(value, str)
            and value.startswith('*')  # a wildcard at the start signifies endswith
        ):
            new_value = self.generateValueNode(value[1:])
            if new_value != (self.valueExpression % value[1:]):
                raise BackendError(
                    'Lacework backend only supports endswith for literal string values')
            return f"{transformed_fieldname} <> {new_value}"
        if (
            self.mapListsSpecialHandling is False and isinstance(value, (str, int, list))
            or self.mapListsSpecialHandling is True and isinstance(value, (str, int))
        ):
            return self.mapExpression % (transformed_fieldname, self.generateNode(value))
        elif type(value) == list:
            return self.generateMapItemListNode(transformed_fieldname, value)
        elif value is None:
            return self.nullExpression % (transformed_fieldname, )
        else:
            raise TypeError(
                f'Lacework backend does not support map values of type {type(value)}')
Example #9
0
 def _check_unsupported_field(action, fieldname):
     if action == 'raise':
         raise BackendError(
             f'Lacework backend does not support the {fieldname} field')