Example #1
0
def ldapRules(context, component, ruleset, rule_type, identifiers):
    logger = ContextLoggerChild(context, component)
    result = ApplyRulesResult(logger)

    if rule_type == 'acls-ipv6':
        rules = ruleset.acls_ipv6
    elif rule_type == 'acls-ipv4':
        rules = ruleset.acls_ipv4
    else:
        # NuFW (LDAP) doesn't authenticate NAT rules
        raise RulesetError(tr("LDAP doesn't support rule type: %s"), repr(rule_type))
    if identifiers:
        rules = [ rules[id] for id in identifiers ]
    else:
        rules = rules

    ldap = WriteLdapRules(logger, component.config['ldap'])
    with TemplateInstanciation(ruleset):
        rules = filterRules(result, rules)

        lines = []
        for dn, attr in ldap.createRules(rules):
            lines.append(unicode(dn))
            attrs = attr.items()
            attrs.sort(key=lambda item: item[0])
            for key, value in attrs:
                lines.append(u"  %s=%r" % (key, value))
            lines.append(u"")
        xmlrpc = result.exportXMLRPC()
        xmlrpc['ldap'] = lines
        return xmlrpc
Example #2
0
def iptablesRules(context, component, ruleset, rule_type, identifiers, use_nufw):
    logger = ContextLoggerChild(context, component)
    result = ApplyRulesResult(logger)

    # Not NAT rules in IPv6!
    if rule_type == 'nats':
        rules = ruleset.nats
        use_ipv6 = False
        default_decisions = None
    elif rule_type == 'acls-ipv6':
        rules = ruleset.acls_ipv6
        use_ipv6 = True
        default_decisions = rules.default_decisions
    else:
        rules = ruleset.acls_ipv4
        use_ipv6 = False
        default_decisions = rules.default_decisions
    if identifiers:
        rules = [ rules[id] for id in identifiers ]
    else:
        rules = rules

    options = IptablesOptions()
    options.format = "iptables"
    options.ipv6 = use_ipv6
    options.nufw = use_nufw

    with TemplateInstanciation(ruleset):
        rules = filterRules(result, rules)

        # Create iptables rules
        iptables = IptablesGenerator(logger, default_decisions, options, component.config, result)
        if rule_type != 'nats':
            lines = aclsRules(iptables, rules)
        else:
            lines = natsRules(iptables, rules, result)
        xmlrpc = result.exportXMLRPC()
        xmlrpc['iptables'] = [unicode(line) for line in lines]
        return xmlrpc
Example #3
0
    def __init__(self, context, component, ruleset, use_nufw,
    raise_error=False, only_consistency=False, consistency_error=False):
        self.context = context
        self.component = component
        self.ruleset = ruleset
        self.use_nufw = use_nufw
        self.only_consistency = only_consistency
        self.logger = ContextLoggerChild(context, component)
        self.result = ApplyRulesResult(self.logger, raise_error, not consistency_error)

        self.config = component.config
        self.lock_manager = component.core.lock_manager
        self.use_ipv6 = self.config['global']['use_ipv6']

        if ruleset:
            # Some consistency checks
            if self.use_nufw and (not self.ruleset.useNuFW()):
                raise RulesetError(tr("NuFW is disabled"))
            if not self.only_consistency and self.ruleset.is_template:
                raise RulesetError(tr("Unable to apply rules of a rule set template"))

            # Get rules
            self.acls_ipv4 = [acl for acl in self.ruleset.acls_ipv4 if acl.enabled]
            self.acls_ipv6 = [acl for acl in self.ruleset.acls_ipv6 if acl.enabled]
            self.nats = [nat for nat in self.ruleset.nats if nat.enabled]
            self.custom_rules = self.ruleset.custom_rules
            self.ruleset_name = self.ruleset.name
            self.ipv4_default_decisions = self.ruleset.acls_ipv4.default_decisions
            self.ipv6_default_decisions = self.ruleset.acls_ipv6.default_decisions
        else:
            # Apply localfw rules with no ruleset
            self.acls_ipv4 = tuple()
            self.acls_ipv6 = tuple()
            self.nats = tuple()
            self.custom_rules = None
            self.ruleset_name = None
            self.ipv4_default_decisions = DefaultDecisions(self.config, False)
            self.ipv6_default_decisions = DefaultDecisions(self.config, True)
Example #4
0
class ApplyRules:
    def __init__(self, context, component, ruleset, use_nufw,
    raise_error=False, only_consistency=False, consistency_error=False):
        self.context = context
        self.component = component
        self.ruleset = ruleset
        self.use_nufw = use_nufw
        self.only_consistency = only_consistency
        self.logger = ContextLoggerChild(context, component)
        self.result = ApplyRulesResult(self.logger, raise_error, not consistency_error)

        self.config = component.config
        self.lock_manager = component.core.lock_manager
        self.use_ipv6 = self.config['global']['use_ipv6']

        if ruleset:
            # Some consistency checks
            if self.use_nufw and (not self.ruleset.useNuFW()):
                raise RulesetError(tr("NuFW is disabled"))
            if not self.only_consistency and self.ruleset.is_template:
                raise RulesetError(tr("Unable to apply rules of a rule set template"))

            # Get rules
            self.acls_ipv4 = [acl for acl in self.ruleset.acls_ipv4 if acl.enabled]
            self.acls_ipv6 = [acl for acl in self.ruleset.acls_ipv6 if acl.enabled]
            self.nats = [nat for nat in self.ruleset.nats if nat.enabled]
            self.custom_rules = self.ruleset.custom_rules
            self.ruleset_name = self.ruleset.name
            self.ipv4_default_decisions = self.ruleset.acls_ipv4.default_decisions
            self.ipv6_default_decisions = self.ruleset.acls_ipv6.default_decisions
        else:
            # Apply localfw rules with no ruleset
            self.acls_ipv4 = tuple()
            self.acls_ipv6 = tuple()
            self.nats = tuple()
            self.custom_rules = None
            self.ruleset_name = None
            self.ipv4_default_decisions = DefaultDecisions(self.config, False)
            self.ipv6_default_decisions = DefaultDecisions(self.config, True)

    def consistencyEngine(self):
        for rules in (self.acls_ipv4, self.acls_ipv6):
            chain = []
            last_chain = None
            for rule in rules:
                new_chain = rule.createChainKey()
                if last_chain and last_chain != new_chain:
                    aclsConsistencyTests(chain, self.result)
                    chain = []
                chain.append(rule)
                last_chain = new_chain
            aclsConsistencyTests(chain, self.result)
        # TODO: test self.nats

    def _applyRulesThread(self):
        if self.only_consistency:
            self.consistencyEngine()
            return self.result.exportXMLRPC()
        elif not self.result.ignore_consistency_error:
            self.consistencyEngine()
            if self.result.consistency_errors:
                return self.result.exportXMLRPC()

        options = IptablesOptions()
        options.nufw = self.use_nufw

        if self.ruleset_name:
            self.logger.critical("Apply rules: rule set %r" % self.ruleset_name)
        else:
            self.logger.critical("Apply rules: no rule set (only localfw rules)")

        write_ldap = WriteLdapRules(self.logger, self.config['ldap'])

        ufwi_ruleset_rules = {
            'use_ipv6': self.use_ipv6,
            'use_nufw': self.use_nufw,
            'is_gateway': self.config.isGateway(),
        }
        if self.use_nufw:
            ufwi_ruleset_rules['ldap_config'] = self.config['ldap']
            if self.use_ipv6:
                acls = itertools.chain(self.acls_ipv4, self.acls_ipv6)
            else:
                acls = self.acls_ipv4
            ufwi_ruleset_rules['ldap_rules'] = write_ldap.createRules(acls)

        # TODO: disable IP forward at the beginning
        # TODO: FORWARD and INPUT: set policy to DROP

        # LDAP
        transactions = []
        if self.use_nufw:
            filename = self.config['nufw']['periods_filename']
            periods = TimeRangeFileTransaction(filename, self.acls_ipv4, self.acls_ipv6)
            transactions.append(periods)

        # iptables
        options.ipv6 = False
        write_iptables_ipv4 = WriteIptablesRules(
            self.logger, self.config, self.ipv4_default_decisions,
            self.acls_ipv4, self.nats, self.custom_rules,
            options, self.result)
        transactions.append(write_iptables_ipv4)

        ipv6_options = deepcopy(options)
        ipv6_options.ipv6 = True
        ipv6_options.deny_all = (not self.use_ipv6)
        write_iptables_ipv6 = WriteIptablesRules(
            self.logger, self.config, self.ipv6_default_decisions,
            self.acls_ipv6, None, self.custom_rules,
            ipv6_options, self.result)
        transactions.append(write_iptables_ipv6)

        # TODO: reload nuauth caches
        # TODO: reload nuauth periods

        # TODO: FORWARD and INPUT: set policy to ACCEPT

        write = WriteRules(self.logger, ufwi_ruleset_rules)
        transactions.append(write)

        script = RulesetScript(self.context, self.logger)
        transactions.append(script)

        save_ruleset = SaveRuleset(self.ruleset_name, self.use_nufw)
        transactions.append(save_ruleset)

        if self.ruleset \
        and (self.ruleset.filename != PRODUCTION_RULESET):
            production = ProductionRuleset(self.ruleset.filename)
            transactions.append(production)

        executeTransactions(self.logger, transactions)

        self.result.applied = True
        return self.result.exportXMLRPC()

    def _checkUserGroup(self, require_group_name, user_group):
        if require_group_name:
            if user_group.name is None:
                raise RulesetError(
                    tr('The firewall uses user group names, but the %s user group has no name'),
                    user_group.formatID())
        else:
            if user_group.group is None:
                raise RulesetError(
                    tr('The firewall uses user group numbers, but the %s user group has no number'),
                    user_group.formatID())

    def checkUserGroups(self):
        require_group_name = self.config['nufw']['require_group_name']
        user_groups = set()
        for rule in itertools.chain(self.acls_ipv4, self.acls_ipv6):
            user_groups |= set(flattenObjectList(rule.user_groups))
        for user_group in user_groups:
            self._checkUserGroup(require_group_name, user_group)

    def applyRules(self):
        if not self.only_consistency:
            self.lock_manager.acquire(self.context, "ufwi_ruleset_applyRules")
        try:
            if self.ruleset:
                with TemplateInstanciation(self.ruleset):
                    self.acls_ipv4 = filterRules(self.result, self.acls_ipv4)
                    self.acls_ipv6 = filterRules(self.result, self.acls_ipv6)
                    self.nats = filterRules(self.result, self.nats)
                    self.checkUserGroups()
                    if self.result.errors:
                        return self.result.exportXMLRPC()
                    return self._applyRulesThread()
            else:
                return self._applyRulesThread()
        finally:
            if not self.only_consistency:
                self.lock_manager.release(self.context, "ufwi_ruleset_applyRules")