Blame org_fedora_oscap/rule_handling.py

Packit 792a06
#
Packit 792a06
# Copyright (C) 2013  Red Hat, Inc.
Packit 792a06
#
Packit 792a06
# This copyrighted material is made available to anyone wishing to use,
Packit 792a06
# modify, copy, or redistribute it subject to the terms and conditions of
Packit 792a06
# the GNU General Public License v.2, or (at your option) any later version.
Packit 792a06
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit 792a06
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit 792a06
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 792a06
# Public License for more details.  You should have received a copy of the
Packit 792a06
# GNU General Public License along with this program; if not, write to the
Packit 792a06
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 792a06
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit 792a06
# source code or documentation are not subject to the GNU General Public
Packit 792a06
# License and may only be used or replicated with the express permission of
Packit 792a06
# Red Hat, Inc.
Packit 792a06
#
Packit 792a06
# Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com>
Packit 792a06
#
Packit 792a06
Packit 792a06
"""
Packit 792a06
Module with various classes for handling pre-installation rules.
Packit 792a06
Packit 792a06
"""
Packit 792a06
Packit 792a06
import optparse
Packit 792a06
import shlex
Packit 792a06
import logging
Packit 792a06
Packit 792a06
from pyanaconda.pwpolicy import F22_PwPolicyData
Packit 792a06
from pyanaconda.core.constants import (
Packit 792a06
    FIREWALL_ENABLED, FIREWALL_DISABLED, FIREWALL_USE_SYSTEM_DEFAULTS)
Packit 792a06
from pyanaconda.modules.common.constants.objects import FIREWALL, BOOTLOADER, DEVICE_TREE
Packit 792a06
from pyanaconda.modules.common.constants.services import NETWORK, STORAGE, USERS
Packit 792a06
Packit 792a06
from org_fedora_oscap import common
Packit 792a06
from org_fedora_oscap.common import OSCAPaddonError, RuleMessage
Packit 792a06
Packit 792a06
# everything else should be private
Packit 792a06
__all__ = ["RuleData"]
Packit 792a06
Packit 792a06
Packit Service 257ff9
ESSENTIAL_PACKAGES = {
Packit Service 257ff9
    "xorg-x11-server-common": {
Packit Service 257ff9
        "env": ["graphical-server-environment", "workstation-product-environment"],
Packit Service 257ff9
    }
Packit Service 257ff9
}
Packit Service 257ff9
Packit 792a06
log = logging.getLogger("anaconda")
Packit 792a06
Packit 792a06
_ = common._
Packit 792a06
Packit 792a06
Packit 792a06
# TODO: use set instead of list for mount options?
Packit 792a06
def parse_csv(option, opt_str, value, parser):
Packit 792a06
    for item in value.split(","):
Packit 792a06
        if item:
Packit 792a06
            parser.values.ensure_value(option.dest, []).append(item)
Packit 792a06
Packit 792a06
Packit 792a06
class ModifiedOptionParserException(Exception):
Packit 792a06
    """Exception to be raised by ModifiedOptionParser."""
Packit 792a06
    pass
Packit 792a06
Packit 792a06
Packit 792a06
class ModifiedOptionParser(optparse.OptionParser):
Packit 792a06
    """Overrides error behavior of OptionParser."""
Packit 792a06
    def error(self, msg):
Packit 792a06
        raise ModifiedOptionParserException(msg)
Packit 792a06
Packit 792a06
    def exit(self, status=0, msg=None):
Packit 792a06
        raise ModifiedOptionParserException(msg)
Packit 792a06
Packit 792a06
Packit 792a06
PART_RULE_PARSER = ModifiedOptionParser()
Packit 792a06
PART_RULE_PARSER.add_option("--mountoptions", dest="mount_options",
Packit 792a06
                            action="callback", callback=parse_csv, nargs=1,
Packit 792a06
                            type="string")
Packit 792a06
Packit 792a06
PASSWD_RULE_PARSER = ModifiedOptionParser()
Packit 792a06
PASSWD_RULE_PARSER.add_option("--minlen", dest="minlen", action="store",
Packit 792a06
                              default=0, type="int")
Packit 792a06
Packit 792a06
PACKAGE_RULE_PARSER = ModifiedOptionParser()
Packit 792a06
PACKAGE_RULE_PARSER.add_option("--add", dest="add_pkgs", action="append",
Packit 792a06
                               type="string")
Packit 792a06
PACKAGE_RULE_PARSER.add_option("--remove", dest="remove_pkgs", action="append",
Packit 792a06
                               type="string")
Packit 792a06
Packit 792a06
BOOTLOADER_RULE_PARSER = ModifiedOptionParser()
Packit 792a06
BOOTLOADER_RULE_PARSER.add_option("--passwd", dest="passwd", action="store_true",
Packit 792a06
                                  default=False)
Packit 792a06
Packit 792a06
KDUMP_RULE_PARSER = ModifiedOptionParser()
Packit 792a06
KDUMP_RULE_PARSER.add_option("--enable", action="store_true",
Packit 792a06
                             dest="kdenabled", default=None)
Packit 792a06
KDUMP_RULE_PARSER.add_option("--disable", action="store_false",
Packit 792a06
                             dest="kdenabled", default=None)
Packit 792a06
Packit 792a06
FIREWALL_RULE_PARSER = ModifiedOptionParser()
Packit 792a06
FIREWALL_RULE_PARSER.add_option("--enable", action="store_true",
Packit 792a06
                                dest="fwenabled", default=None)
Packit 792a06
FIREWALL_RULE_PARSER.add_option("--disable", action="store_false",
Packit 792a06
                                dest="fwenabled", default=None)
Packit 792a06
FIREWALL_RULE_PARSER.add_option("--service", dest="add_svcs", action="append",
Packit 792a06
                                type="string")
Packit 792a06
FIREWALL_RULE_PARSER.add_option("--port", dest="add_port", action="append",
Packit 792a06
                                type="string")
Packit 792a06
FIREWALL_RULE_PARSER.add_option("--trust", dest="add_trust", action="append",
Packit 792a06
                                type="string")
Packit 792a06
FIREWALL_RULE_PARSER.add_option("--remove-service", dest="remove_svcs",
Packit 792a06
                                action="append", type="string")
Packit 792a06
Packit 792a06
Packit 792a06
class RuleHandler(object):
Packit 792a06
    """Base class for the rule handlers."""
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """
Packit 792a06
        Method that should check the current state (as defined by the ksdata
Packit 792a06
        and storage parameters) against the rules the instance of RuleHandler
Packit 792a06
        holds. Depending on the value of report_only it should fix the state
Packit 792a06
        with changes that can be done automatically or not and return the list
Packit 792a06
        of warnings and errors for fixes that need to be done manually together
Packit 792a06
        with info messages about the automatic changes. One should make sure
Packit 792a06
        this method is called with report_only set to False at least once so
Packit 792a06
        that the automatic fixes are done.
Packit 792a06
Packit 792a06
        :param ksdata: data representing the values set by user
Packit 792a06
        :type ksdata: pykickstart.base.BaseHandler
Packit 792a06
        :param storage: object storing storage-related information
Packit 792a06
                        (disks, partitioning, bootloader, etc.)
Packit 792a06
        :type storage: blivet.Blivet
Packit 792a06
        :param report_only: whether to do fixing or just report information
Packit 792a06
        :type report_only: bool
Packit 792a06
        :return: errors and warnings for fixes that need to be done manually
Packit 792a06
                 and info messages about the automatic changes
Packit 792a06
        :rtype: list of common.RuleMessage objects
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        return []
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """
Packit 792a06
        Method that should revert all changes done by the previous calls of the
Packit 792a06
        eval_rules method with the report_only set to False.
Packit 792a06
Packit 792a06
        :see: eval_rules
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        # inheriting classes are supposed to override this
Packit 792a06
        pass
Packit 792a06
Packit 792a06
Packit 792a06
class UknownRuleError(OSCAPaddonError):
Packit 792a06
    """Exception class for cases when an uknown rule is to be processed."""
Packit 792a06
Packit 792a06
    pass
Packit 792a06
Packit 792a06
Packit 792a06
class RuleData(RuleHandler):
Packit 792a06
    """Class holding data parsed from the applied rules."""
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor initializing attributes."""
Packit 792a06
Packit 792a06
        self._part_rules = PartRules()
Packit 792a06
        self._passwd_rules = PasswdRules()
Packit 792a06
        self._package_rules = PackageRules()
Packit 792a06
        self._bootloader_rules = BootloaderRules()
Packit 792a06
        self._kdump_rules = KdumpRules()
Packit 792a06
        self._firewall_rules = FirewallRules()
Packit 792a06
Packit 792a06
        self._rule_handlers = (self._part_rules, self._passwd_rules,
Packit 792a06
                               self._package_rules, self._bootloader_rules,
Packit 792a06
                               self._kdump_rules, self._firewall_rules,
Packit 792a06
                               )
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        ret = ""
Packit 792a06
Packit 792a06
        part_strs = str(self._part_rules)
Packit 792a06
        if part_strs:
Packit 792a06
            ret += part_strs
Packit 792a06
Packit 792a06
        passwd_str = str(self._passwd_rules)
Packit 792a06
        if passwd_str:
Packit 792a06
            ret += "\n" + passwd_str
Packit 792a06
Packit 792a06
        packages_str = str(self._package_rules)
Packit 792a06
        if packages_str:
Packit 792a06
            ret += "\n" + packages_str
Packit 792a06
Packit 792a06
        firewall_str = str(self._firewall_rules)
Packit 792a06
        if firewall_str:
Packit 792a06
            ret += "\n" + firewall_str
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit 792a06
    def new_rule(self, rule):
Packit 792a06
        """
Packit 792a06
        Method that handles a single rule line (e.g. "part /tmp").
Packit 792a06
Packit 792a06
        :param rule: a single rule line
Packit 792a06
        :type rule: str
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        actions = {"part": self._new_part_rule,
Packit 792a06
                   "passwd": self._new_passwd_rule,
Packit 792a06
                   "package": self._new_package_rule,
Packit 792a06
                   "bootloader": self._new_bootloader_rule,
Packit 792a06
                   "kdump": self._new_kdump_rule,
Packit 792a06
                   "firewall": self._new_firewall_rule,
Packit 792a06
                   }
Packit 792a06
Packit 792a06
        rule = rule.strip()
Packit 792a06
        if not rule:
Packit 792a06
            return
Packit 792a06
Packit 792a06
        first_word = rule.split(None, 1)[0]
Packit 792a06
        try:
Packit 792a06
            actions[first_word](rule)
Packit 792a06
        except (ModifiedOptionParserException, KeyError) as e:
Packit 792a06
            log.warning("Unknown OSCAP Addon rule '{}': {}".format(rule, e))
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        messages = []
Packit 792a06
Packit 792a06
        # evaluate all subgroups of rules
Packit 792a06
        for rule_handler in self._rule_handlers:
Packit 792a06
            messages += rule_handler.eval_rules(ksdata, storage, report_only)
Packit 792a06
Packit 792a06
        return messages
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """:see: RuleHandler.revert_changes"""
Packit 792a06
Packit 792a06
        # revert changes in all subgroups of rules
Packit 792a06
        for rule_handler in self._rule_handlers:
Packit 792a06
            rule_handler.revert_changes(ksdata, storage)
Packit 792a06
Packit 792a06
    def _new_part_rule(self, rule):
Packit 792a06
        args = shlex.split(rule)
Packit 792a06
        (opts, args) = PART_RULE_PARSER.parse_args(args)
Packit 792a06
Packit 792a06
        # args contain both "part" and mount point (e.g. "/tmp")
Packit 792a06
        mount_point = args[1]
Packit 792a06
Packit 792a06
        self._part_rules.ensure_mount_point(mount_point)
Packit 792a06
Packit 792a06
        if opts.mount_options:
Packit 792a06
            part_data = self._part_rules[mount_point]
Packit 792a06
            part_data.add_mount_options(opts.mount_options)
Packit 792a06
Packit 792a06
    def _new_passwd_rule(self, rule):
Packit 792a06
        args = shlex.split(rule)
Packit 792a06
        (opts, args) = PASSWD_RULE_PARSER.parse_args(args)
Packit 792a06
Packit 792a06
        self._passwd_rules.update_minlen(opts.minlen)
Packit 792a06
Packit 792a06
    def _new_package_rule(self, rule):
Packit 792a06
        args = shlex.split(rule)
Packit 792a06
        (opts, args) = PACKAGE_RULE_PARSER.parse_args(args)
Packit 792a06
Packit 792a06
        self._package_rules.add_packages(opts.add_pkgs)
Packit 792a06
        self._package_rules.remove_packages(opts.remove_pkgs)
Packit 792a06
Packit 792a06
    def _new_bootloader_rule(self, rule):
Packit 792a06
        args = shlex.split(rule)
Packit 792a06
        (opts, args) = BOOTLOADER_RULE_PARSER.parse_args(args)
Packit 792a06
Packit 792a06
        if opts.passwd:
Packit 792a06
            self._bootloader_rules.require_password()
Packit 792a06
Packit 792a06
    def _new_kdump_rule(self, rule):
Packit 792a06
        args = shlex.split(rule)
Packit 792a06
        (opts, args) = KDUMP_RULE_PARSER.parse_args(args)
Packit 792a06
Packit 792a06
        self._kdump_rules.kdump_enabled(opts.kdenabled)
Packit 792a06
Packit 792a06
    def _new_firewall_rule(self, rule):
Packit 792a06
        args = shlex.split(rule)
Packit 792a06
        (opts, args) = FIREWALL_RULE_PARSER.parse_args(args)
Packit 792a06
Packit 792a06
        self._firewall_rules.add_services(opts.add_svcs)
Packit 792a06
        self._firewall_rules.remove_services(opts.remove_svcs)
Packit 792a06
        self._firewall_rules.add_trusts(opts.add_trust)
Packit 792a06
        self._firewall_rules.add_ports(opts.add_port)
Packit 792a06
        self._firewall_rules.firewall_enabled(opts.fwenabled)
Packit 792a06
Packit 792a06
    @property
Packit 792a06
    def passwd_rules(self):
Packit 792a06
        # needed for fixups in GUI
Packit 792a06
        return self._passwd_rules
Packit 792a06
Packit 792a06
Packit 792a06
class PartRules(RuleHandler):
Packit 792a06
    """Simple class holding data from the rules affecting partitioning."""
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor initializing attributes."""
Packit 792a06
Packit 792a06
        self._rules = dict()
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        return "\n".join(str(rule) for rule in self._rules.values())
Packit 792a06
Packit 792a06
    def __getitem__(self, key):
Packit 792a06
        """Method to support dictionary-like syntax."""
Packit 792a06
Packit 792a06
        return self._rules[key]
Packit 792a06
Packit 792a06
    def __setitem__(self, key, value):
Packit 792a06
        """Method to support dictionary-like syntax."""
Packit 792a06
Packit 792a06
        self._rules[key] = value
Packit 792a06
Packit 792a06
    def __delitem__(self, key):
Packit 792a06
        """One of the methods needed to implement a container."""
Packit 792a06
Packit 792a06
        self._rules.__delitem__(key)
Packit 792a06
Packit 792a06
    def __len__(self):
Packit 792a06
        """One of the methods needed to implement a container."""
Packit 792a06
Packit 792a06
        return self._rules.__len__()
Packit 792a06
Packit 792a06
    def __contains__(self, key):
Packit 792a06
        """Method needed for the 'in' operator to work."""
Packit 792a06
Packit 792a06
        return key in self._rules
Packit 792a06
Packit 792a06
    def ensure_mount_point(self, mount_point):
Packit 792a06
        if mount_point not in self._rules:
Packit 792a06
            self._rules[mount_point] = PartRule(mount_point)
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        messages = []
Packit 792a06
        for part_rule in self._rules.values():
Packit 792a06
            messages += part_rule.eval_rules(ksdata, storage, report_only)
Packit 792a06
Packit 792a06
        return messages
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """:see: RuleHandler.revert_changes"""
Packit 792a06
Packit 792a06
        for part_rule in self._rules.values():
Packit 792a06
            part_rule.revert_changes(ksdata, storage)
Packit 792a06
Packit 792a06
Packit 792a06
class PartRule(RuleHandler):
Packit 792a06
    """Simple class holding rule data for a single partition/mount point."""
Packit 792a06
Packit 792a06
    def __init__(self, mount_point):
Packit 792a06
        """
Packit 792a06
        Constructor initializing attributes.
Packit 792a06
Packit 792a06
        :param mount_point: the mount point the object holds data for
Packit 792a06
        :type mount_point: str
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        self._mount_point = mount_point
Packit 792a06
        self._mount_options = []
Packit 792a06
        self._added_mount_options = []
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        ret = "part %s" % self._mount_point
Packit 792a06
        if self._mount_options:
Packit 792a06
            ret += " --mountoptions=%s" % ",".join(self._mount_options)
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit 792a06
    def add_mount_options(self, mount_options):
Packit 792a06
        """
Packit 792a06
        Add  new mount options (do not add duplicates).
Packit 792a06
Packit 792a06
        :param mount_options: list of mount options to be added
Packit 792a06
        :type mount_options: list of strings
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        self._mount_options.extend(opt for opt in mount_options
Packit 792a06
                                   if opt not in self._mount_options)
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
        device_tree = STORAGE.get_proxy(DEVICE_TREE)
Packit 792a06
        mount_points = device_tree.GetMountPoints()
Packit 792a06
        messages = []
Packit 792a06
Packit 792a06
        if self._mount_point not in mount_points:
Packit 792a06
            msg = _("{0} must be on a separate partition or logical "
Packit 792a06
                    "volume and has to be created in the "
Packit 792a06
                    "partitioning layout before installation can occur "
Packit 792a06
                    "with a security profile").format(self._mount_point)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_FATAL, msg))
Packit 792a06
Packit 792a06
            # mount point doesn't exist, nothing more can be found here
Packit 792a06
            return messages
Packit 792a06
Packit 792a06
        # template for the message
Packit 792a06
        msg_tmpl = _("mount option '%(mount_option)s' added for "
Packit 792a06
                     "the mount point %(mount_point)s")
Packit 792a06
Packit 792a06
        # add message for every option already added
Packit 792a06
        for opt in self._added_mount_options:
Packit 792a06
            msg = msg_tmpl % {"mount_option": opt,
Packit 792a06
                              "mount_point": self._mount_point}
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # mount point to be created during installation
Packit 792a06
        target_name = mount_points[self._mount_point]
Packit 792a06
        mount_options = device_tree.GetDeviceMountOptions(target_name)
Packit 792a06
Packit 792a06
        # generator for the new options that should be added
Packit 792a06
        new_opts = (opt for opt in self._mount_options
Packit 792a06
                    if opt not in mount_options.split(","))
Packit 792a06
Packit 792a06
        # add message for every mount option added
Packit 792a06
        for opt in new_opts:
Packit 792a06
            msg = msg_tmpl % {"mount_option": opt,
Packit 792a06
                              "mount_point": self._mount_point}
Packit 792a06
Packit 792a06
            # add message for the mount option in any case
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
            # add new options to the target mount point if not reporting only
Packit 792a06
            if not report_only:
Packit 792a06
                mount_options += ",%s" % opt
Packit 792a06
                self._added_mount_options.append(opt)
Packit 792a06
Packit 792a06
        if new_opts and not report_only:
Packit 792a06
            device_tree.SetDeviceMountOptions(target_name, mount_options)
Packit 792a06
Packit 792a06
        return messages
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """
Packit 792a06
        Removes the mount options added to the mount point by this PartRule
Packit 792a06
        instance.
Packit 792a06
Packit 792a06
        :see: RuleHandler.revert_changes
Packit 792a06
Packit 792a06
        """
Packit 792a06
        device_tree = STORAGE.get_proxy(DEVICE_TREE)
Packit 792a06
        mount_points = device_tree.GetMountPoints()
Packit 792a06
Packit 792a06
        if self._mount_point not in mount_points:
Packit 792a06
            # mount point doesn't exist, nothing can be reverted
Packit 792a06
            return
Packit 792a06
Packit 792a06
        # mount point to be created during installation
Packit 792a06
        target_name = mount_points[self._mount_point]
Packit 792a06
Packit 792a06
        # mount options to be defined for the created mount point
Packit 792a06
        mount_options = device_tree.GetDeviceMountOptions(target_name)
Packit 792a06
Packit 792a06
        # generator of the options that should remain
Packit 792a06
        result_opts = (opt for opt in mount_options.split(",")
Packit 792a06
                       if opt not in self._added_mount_options)
Packit 792a06
Packit 792a06
        # set the new list of options
Packit 792a06
        mount_options = ",".join(result_opts)
Packit 792a06
        device_tree.SetDeviceMountOptions(target_name, mount_options)
Packit 792a06
Packit 792a06
        # reset the remembered added mount options
Packit 792a06
        self._added_mount_options = []
Packit 792a06
Packit 792a06
Packit 792a06
class PasswdRules(RuleHandler):
Packit 792a06
    """Simple class holding data from the rules affecting passwords."""
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor initializing attributes."""
Packit 792a06
Packit 792a06
        self._minlen = 0
Packit 792a06
        self._created_policy = False
Packit 792a06
        self._orig_minlen = None
Packit 792a06
        self._orig_strict = None
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        if self._minlen > 0:
Packit 792a06
            return "passwd --minlen=%d" % self._minlen
Packit 792a06
        else:
Packit 792a06
            return ""
Packit 792a06
Packit 792a06
    def update_minlen(self, minlen):
Packit 792a06
        """Update password minimal length requirements."""
Packit 792a06
Packit 792a06
        if minlen > self._minlen:
Packit 792a06
            self._minlen = minlen
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        if self._minlen == 0:
Packit 792a06
            # no password restrictions, nothing to be done here
Packit 792a06
            return []
Packit 792a06
Packit 792a06
        ret = []
Packit 792a06
Packit 792a06
        users_proxy = USERS.get_proxy()
Packit 792a06
Packit 792a06
        if not users_proxy.IsRootPasswordSet:
Packit 792a06
            # root password was not set
Packit 792a06
Packit 792a06
            msg = _("make sure to create password with minimal length of %d "
Packit 792a06
                    "characters") % self._minlen
Packit 792a06
            ret = [RuleMessage(self.__class__,
Packit 792a06
                               common.MESSAGE_TYPE_WARNING, msg)]
Packit 792a06
        else:
Packit 792a06
            # root password set
Packit 792a06
            if users_proxy.IsRootPasswordCrypted:
Packit 792a06
                msg = _("cannot check root password length (password is crypted)")
Packit 792a06
                log.warning("cannot check root password length (password is crypted)")
Packit 792a06
                return [RuleMessage(self.__class__,
Packit 792a06
                                    common.MESSAGE_TYPE_WARNING, msg)]
Packit 792a06
            elif len(users_proxy.RootPassword) < self._minlen:
Packit 792a06
                # too short
Packit 792a06
                msg = _("root password is too short, a longer one with at "
Packit 792a06
                        "least %d characters is required") % self._minlen
Packit 792a06
                ret = [RuleMessage(self.__class__,
Packit 792a06
                                   common.MESSAGE_TYPE_FATAL, msg)]
Packit 792a06
            else:
Packit 792a06
                ret = []
Packit 792a06
Packit 792a06
        if report_only:
Packit 792a06
            return ret
Packit 792a06
Packit 792a06
        # set the policy in any case (so that a weaker password is not entered)
Packit 792a06
        pw_policy = ksdata.anaconda.pwpolicy.get_policy("root")
Packit 792a06
        if pw_policy is None:
Packit 792a06
            pw_policy = F22_PwPolicyData()
Packit 792a06
            log.info("OSCAP addon: setting password policy %s" % pw_policy)
Packit 792a06
            ksdata.anaconda.pwpolicy.policyList.append(pw_policy)
Packit 792a06
            log.info("OSCAP addon: password policy list: %s" % ksdata.anaconda.pwpolicy.policyList)
Packit 792a06
            self._created_policy = True
Packit 792a06
Packit 792a06
        self._orig_minlen = pw_policy.minlen
Packit 792a06
        self._orig_strict = pw_policy.strict
Packit 792a06
        pw_policy.minlen = self._minlen
Packit 792a06
        pw_policy.strict = True
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """:see: RuleHander.revert_changes"""
Packit 792a06
Packit 792a06
        pw_policy = ksdata.anaconda.pwpolicy.get_policy("root")
Packit 792a06
        if self._created_policy:
Packit 792a06
            log.info("OSCAP addon: removing password policy: %s" % pw_policy)
Packit 792a06
            ksdata.anaconda.pwpolicy.policyList.remove(pw_policy)
Packit 792a06
            log.info("OSCAP addon: password policy list: %s" % ksdata.anaconda.pwpolicy.policyList)
Packit 792a06
            self._created_policy = False
Packit 792a06
        else:
Packit 792a06
            if self._orig_minlen is not None:
Packit 792a06
                pw_policy.minlen = self._orig_minlen
Packit 792a06
                self._orig_minlen = None
Packit 792a06
            if self._orig_strict is not None:
Packit 792a06
                pw_policy.strict = self._orig_strict
Packit 792a06
                self._orig_strict = None
Packit 792a06
Packit 792a06
Packit 792a06
class PackageRules(RuleHandler):
Packit 792a06
    """Simple class holding data from the rules affecting installed packages.
Packit 792a06
Packit 792a06
    """
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor setting the initial value of attributes."""
Packit 792a06
Packit 792a06
        self._add_pkgs = set()
Packit 792a06
        self._remove_pkgs = set()
Packit 792a06
Packit 792a06
        self._added_pkgs = set()
Packit 792a06
        self._removed_pkgs = set()
Packit 792a06
Packit 792a06
    def add_packages(self, packages):
Packit 792a06
        """
Packit 792a06
        New packages that should be added.
Packit 792a06
Packit 792a06
        :param packages: packages to be added
Packit 792a06
        :type packages: iterable
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        if packages:
Packit 792a06
            self._add_pkgs.update(packages)
Packit 792a06
Packit 792a06
    def remove_packages(self, packages):
Packit 792a06
        """
Packit 792a06
        New packages that should be removed.
Packit 792a06
Packit 792a06
        :param packages: packages to be removed
Packit 792a06
        :type packages: iterable
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        if packages:
Packit 792a06
            self._remove_pkgs.update(packages)
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        ret = "packages"
Packit 792a06
        adds = " ".join("--add=%s" % package for package in self._add_pkgs)
Packit 792a06
        if adds:
Packit 792a06
            ret += " " + adds
Packit 792a06
Packit 792a06
        rems = " ".join("--remove=%s" % package
Packit 792a06
                        for package in self._remove_pkgs)
Packit 792a06
        if rems:
Packit 792a06
            ret += " " + rems
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit Service 257ff9
    def _package_is_essential(self, package_name, ksdata_packages):
Packit Service 257ff9
        if package_name not in ESSENTIAL_PACKAGES:
Packit Service 257ff9
            return False
Packit Service 257ff9
        if package_name in ksdata_packages.packageList:
Packit Service 257ff9
            return True
Packit Service 257ff9
        selected_install_env = ksdata_packages.environment
Packit Service 257ff9
        if selected_install_env in ESSENTIAL_PACKAGES[package_name].get("env"):
Packit Service 257ff9
            return True
Packit Service 257ff9
        selected_install_groups_names = {g.name for g in ksdata_packages.groupList}
Packit Service 257ff9
        for g in ESSENTIAL_PACKAGES[package_name].get("groups", []):
Packit Service 257ff9
            if g in selected_install_groups_names:
Packit Service 257ff9
                return True
Packit Service 257ff9
        return False
Packit Service 257ff9
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        messages = []
Packit 792a06
Packit 792a06
        # add messages for the already added packages
Packit 792a06
        for pkg in self._added_pkgs:
Packit 792a06
            msg = _("package '%s' has been added to the list of to be installed "
Packit 792a06
                    "packages" % pkg)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # packages, that should be added
Packit 792a06
        packages_to_add = (pkg for pkg in self._add_pkgs
Packit 792a06
                           if pkg not in ksdata.packages.packageList)
Packit 792a06
Packit 792a06
        for pkg in packages_to_add:
Packit 792a06
            # add the package unless already added
Packit 792a06
            if not report_only:
Packit 792a06
                self._added_pkgs.add(pkg)
Packit 792a06
                ksdata.packages.packageList.append(pkg)
Packit 792a06
Packit 792a06
            msg = _("package '%s' has been added to the list of to be installed "
Packit 792a06
                    "packages" % pkg)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # now do the same for the packages that should be excluded
Packit 792a06
        # add messages for the already excluded packages
Packit 792a06
        for pkg in self._removed_pkgs:
Packit Service 257ff9
            if self._package_is_essential(pkg, ksdata.packages):
Packit Service 257ff9
                msg = _(
Packit Service 257ff9
                    "package '{package}' has been added to the list "
Packit Service 257ff9
                    "of excluded packages, but it can't be removed "
Packit Service 257ff9
                    "from the current software selection without breaking the installation."
Packit Service 257ff9
                    .format(package=pkg))
Packit Service 257ff9
                messages.append(RuleMessage(self.__class__,
Packit Service 257ff9
                                            common.MESSAGE_TYPE_FATAL, msg))
Packit Service 257ff9
            else:
Packit Service 257ff9
                msg = _("package '%s' has been added to the list of excluded "
Packit Service 257ff9
                        "packages" % pkg)
Packit Service 257ff9
                messages.append(RuleMessage(self.__class__,
Packit Service 257ff9
                                            common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # packages, that should be added
Packit 792a06
        packages_to_remove = (pkg for pkg in self._remove_pkgs
Packit 792a06
                              if pkg not in ksdata.packages.excludedList)
Packit 792a06
Packit 792a06
        for pkg in packages_to_remove:
Packit 792a06
            # exclude the package unless already excluded
Packit 792a06
            if not report_only:
Packit 792a06
                self._removed_pkgs.add(pkg)
Packit 792a06
                ksdata.packages.excludedList.append(pkg)
Packit 792a06
Packit 792a06
            msg = _("package '%s' has been added to the list of excluded "
Packit 792a06
                    "packages" % pkg)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        return messages
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """:see: RuleHander.revert_changes"""
Packit 792a06
Packit 792a06
        # remove all packages this handler added
Packit 792a06
        for pkg in self._added_pkgs:
Packit 792a06
            if pkg in ksdata.packages.packageList:
Packit 792a06
                ksdata.packages.packageList.remove(pkg)
Packit 792a06
Packit 792a06
        # remove all packages this handler excluded
Packit 792a06
        for pkg in self._removed_pkgs:
Packit 792a06
            if pkg in ksdata.packages.excludedList:
Packit 792a06
                ksdata.packages.excludedList.remove(pkg)
Packit 792a06
Packit 792a06
        self._added_pkgs = set()
Packit 792a06
        self._removed_pkgs = set()
Packit 792a06
Packit 792a06
Packit 792a06
class BootloaderRules(RuleHandler):
Packit 792a06
    """Simple class holding data from the rules affecting bootloader."""
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor setting the initial value of attributes."""
Packit 792a06
Packit 792a06
        self._require_password = False
Packit 792a06
Packit 792a06
    def require_password(self):
Packit 792a06
        """Requests the bootloader password should be required."""
Packit 792a06
Packit 792a06
        self._require_password = True
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        ret = "bootloader"
Packit 792a06
Packit 792a06
        if self._require_password:
Packit 792a06
            ret += " --passwd"
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        bootloader_proxy = STORAGE.get_proxy(BOOTLOADER)
Packit 792a06
Packit 792a06
        if self._require_password and not bootloader_proxy.IsPasswordSet:
Packit 792a06
            # TODO: Anaconda provides a way to set bootloader password:
Packit 792a06
            # bootloader_proxy.SetEncryptedPassword(...)
Packit 792a06
            # We don't support setting the bootloader password yet,
Packit 792a06
            # but we shouldn't stop the installation, just because of that.
Packit 792a06
            return [RuleMessage(self.__class__, common.MESSAGE_TYPE_WARNING,
Packit 792a06
                                "boot loader password not set up")]
Packit 792a06
        else:
Packit 792a06
            return []
Packit 792a06
Packit 792a06
    # nothing to be reverted for now
Packit 792a06
Packit 792a06
Packit 792a06
class KdumpRules(RuleHandler):
Packit 792a06
    """Simple class holding data from the rules affecting the kdump addon."""
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor setting the initial value of attributes."""
Packit 792a06
Packit 792a06
        self._kdump_enabled = None
Packit 792a06
        self._kdump_default_enabled = None
Packit 792a06
Packit 792a06
    def kdump_enabled(self, kdenabled):
Packit 792a06
        """Enable or Disable Kdump"""
Packit 792a06
Packit 792a06
        if kdenabled is not None:
Packit 792a06
            self._kdump_enabled = kdenabled
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        ret = "kdump"
Packit 792a06
Packit 792a06
        if self._kdump_enabled is True:
Packit 792a06
            ret += " --enable"
Packit 792a06
Packit 792a06
        if self._kdump_enabled is False:
Packit 792a06
            ret += " --disable"
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        messages = []
Packit 792a06
Packit 792a06
        if self._kdump_enabled is None:
Packit 792a06
            return []
Packit 792a06
        elif self._kdump_enabled is False:
Packit 792a06
            msg = _("Kdump will be disabled on startup")
Packit 792a06
        elif self._kdump_enabled is True:
Packit 792a06
            msg = _("Kdump will be enabled on startup")
Packit 792a06
Packit 792a06
        messages.append(RuleMessage(self.__class__,
Packit 792a06
                                    common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        if not report_only:
Packit 792a06
            try:
Packit 792a06
                if self._kdump_default_enabled is None:
Packit 792a06
                    # Kdump addon default startup setting
Packit 792a06
                    self._kdump_default_enabled = ksdata.addons.com_redhat_kdump.enabled
Packit 792a06
                ksdata.addons.com_redhat_kdump.enabled = self._kdump_enabled
Packit 792a06
            except AttributeError:
Packit 792a06
                log.warning("com_redhat_kdump is not installed. "
Packit 792a06
                            "Skipping kdump configuration")
Packit 792a06
Packit 792a06
        return messages
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """:see: RuleHander.revert_changes"""
Packit 792a06
Packit 792a06
        try:
Packit 792a06
            if self._kdump_enabled is not None:
Packit 792a06
                ksdata.addons.com_redhat_kdump.enabled = self._kdump_default_enabled
Packit 792a06
        except AttributeError:
Packit 792a06
            log.warning("com_redhat_kdump is not installed. "
Packit 792a06
                        "Skipping reverting kdump configuration")
Packit 792a06
Packit 792a06
        self._kdump_enabled = None
Packit 792a06
        self._kdump_default_enabled = None
Packit 792a06
Packit 792a06
Packit 792a06
class FirewallRules(RuleHandler):
Packit 792a06
    """Simple class holding data from the rules affecting firewall configurations."""
Packit 792a06
Packit 792a06
    def __init__(self):
Packit 792a06
        """Constructor setting the initial value of attributes."""
Packit 792a06
Packit 792a06
        self._add_svcs = set()
Packit 792a06
        self._remove_svcs = set()
Packit 792a06
        self._add_trusts = set()
Packit 792a06
        self._add_ports = set()
Packit 792a06
Packit 792a06
        self._added_svcs = set()
Packit 792a06
        self._added_ports = set()
Packit 792a06
        self._added_trusts = set()
Packit 792a06
        self._removed_svcs = set()
Packit 792a06
Packit 792a06
        self._new_services_to_add = set()
Packit 792a06
        self._new_ports_to_add = set()
Packit 792a06
        self._new_trusts_to_add = set()
Packit 792a06
        self._new_services_to_remove = set()
Packit 792a06
Packit 792a06
        self._firewall_enabled = None
Packit 792a06
        self._firewall_default_state = None
Packit 792a06
Packit 792a06
    def add_services(self, services):
Packit 792a06
        """
Packit 792a06
        Services that should be allowed through firewall.
Packit 792a06
Packit 792a06
        :param services: services to be added
Packit 792a06
        :type services: iterable
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        if services:
Packit 792a06
            self._add_svcs.update(services)
Packit 792a06
Packit 792a06
    def add_ports(self, ports):
Packit 792a06
        """
Packit 792a06
        Ports that should be allowed through firewall.
Packit 792a06
Packit 792a06
        :param ports: ports to be added
Packit 792a06
        :type ports: iterable
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        if ports:
Packit 792a06
            self._add_ports.update(ports)
Packit 792a06
Packit 792a06
    def add_trusts(self, trusts):
Packit 792a06
        """
Packit 792a06
        trusts that should be allowed through firewall.
Packit 792a06
Packit 792a06
        :param trusts: trusts to be added
Packit 792a06
        :type trusts: iterable
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        if trusts:
Packit 792a06
            self._add_trusts.update(trusts)
Packit 792a06
Packit 792a06
    def remove_services(self, services):
Packit 792a06
        """
Packit 792a06
        New services that should not be allowed through firewall.
Packit 792a06
Packit 792a06
        :param services: services to be removed
Packit 792a06
        :type services: iterable
Packit 792a06
Packit 792a06
        """
Packit 792a06
Packit 792a06
        if services:
Packit 792a06
            self._remove_svcs.update(services)
Packit 792a06
Packit 792a06
    def firewall_enabled(self, fwenabled):
Packit 792a06
        """Enable or disable firewall"""
Packit 792a06
Packit 792a06
        if fwenabled is not None:
Packit 792a06
            self._firewall_enabled = fwenabled
Packit 792a06
Packit 792a06
    def __str__(self):
Packit 792a06
        """Standard method useful for debugging and testing."""
Packit 792a06
Packit 792a06
        ret = "firewall"
Packit 792a06
Packit 792a06
        if self._firewall_enabled is True:
Packit 792a06
            ret += " --enable"
Packit 792a06
Packit 792a06
        if self._firewall_enabled is False:
Packit 792a06
            ret += " --disable"
Packit 792a06
Packit 792a06
        adds = " ".join("--service=%s" % service
Packit 792a06
                        for service in self._add_svcs)
Packit 792a06
        if adds:
Packit 792a06
            ret += " " + adds
Packit 792a06
Packit 792a06
        rems = " ".join("--remove-service=%s" % service
Packit 792a06
                        for service in self._remove_svcs)
Packit 792a06
        if rems:
Packit 792a06
            ret += " " + rems
Packit 792a06
Packit 792a06
        ports = " ".join("--port=%s" % port
Packit 792a06
                         for port in self._add_ports)
Packit 792a06
        if ports:
Packit 792a06
            ret += " " + ports
Packit 792a06
Packit 792a06
        trusts = " ".join("--trust=%s" % trust
Packit 792a06
                          for trust in self._add_trusts)
Packit 792a06
        if trusts:
Packit 792a06
            ret += " " + trusts
Packit 792a06
Packit 792a06
        return ret
Packit 792a06
Packit 792a06
    def eval_rules(self, ksdata, storage, report_only=False):
Packit 792a06
        """:see: RuleHandler.eval_rules"""
Packit 792a06
Packit 792a06
        firewall_proxy = NETWORK.get_proxy(FIREWALL)
Packit 792a06
        messages = []
Packit 792a06
Packit 792a06
        if self._firewall_default_state is None:
Packit 792a06
            # firewall default startup setting
Packit 792a06
            self._firewall_default_state = firewall_proxy.FirewallMode
Packit 792a06
Packit 792a06
        if self._firewall_enabled is False:
Packit 792a06
            msg = _("Firewall will be disabled on startup")
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
            if not report_only:
Packit 792a06
                firewall_proxy.SetFirewallMode(FIREWALL_DISABLED)
Packit 792a06
Packit 792a06
        elif self._firewall_enabled is True:
Packit 792a06
            msg = _("Firewall will be enabled on startup")
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
            if not report_only:
Packit 792a06
                firewall_proxy.SetFirewallMode(FIREWALL_ENABLED)
Packit 792a06
Packit 792a06
        # add messages for the already added services
Packit 792a06
        for svc in self._added_svcs:
Packit 792a06
            msg = _("service '%s' has been added to the list of services to be "
Packit 792a06
                    "added to the firewall" % svc)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # add messages for the already added ports
Packit 792a06
        for port in self._added_ports:
Packit 792a06
            msg = _("port '%s' has been added to the list of ports to be "
Packit 792a06
                    "added to the firewall" % port)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # add messages for the already added trusts
Packit 792a06
        for trust in self._added_trusts:
Packit 792a06
            msg = _("trust '%s' has been added to the list of trusts to be "
Packit 792a06
                    "added to the firewall" % trust)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # services, that should be added
Packit 792a06
        self._new_services_to_add = {
Packit 792a06
            svc for svc in self._add_svcs
Packit 792a06
            if svc not in firewall_proxy.EnabledServices}
Packit 792a06
Packit 792a06
        # ports, that should be added
Packit 792a06
        self._new_ports_to_add = {
Packit 792a06
            ports for ports in self._add_ports
Packit 792a06
            if ports not in firewall_proxy.EnabledPorts}
Packit 792a06
Packit 792a06
        # trusts, that should be added
Packit 792a06
        self._new_trusts_to_add = {
Packit 792a06
            trust for trust in self._add_trusts
Packit 792a06
            if trust not in firewall_proxy.Trusts}
Packit 792a06
Packit 792a06
        for svc in self._new_services_to_add:
Packit 792a06
            # add the service unless already added
Packit 792a06
            if not report_only:
Packit 792a06
                self._added_svcs.add(svc)
Packit 792a06
Packit 792a06
            msg = _("service '%s' has been added to the list of services to be "
Packit 792a06
                    "added to the firewall" % svc)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
        if not report_only:
Packit 792a06
            all_services = list(self._add_svcs.union(set(firewall_proxy.EnabledServices)))
Packit 792a06
            firewall_proxy.SetEnabledServices(all_services)
Packit 792a06
Packit 792a06
        for port in self._new_ports_to_add:
Packit 792a06
            # add the port unless already added
Packit 792a06
            if not report_only:
Packit 792a06
                self._added_ports.add(port)
Packit 792a06
Packit 792a06
            msg = _("port '%s' has been added to the list of ports to be "
Packit 792a06
                    "added to the firewall" % port)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
        if not report_only:
Packit 792a06
            all_ports = list(self._add_ports.union(set(firewall_proxy.EnabledPorts)))
Packit 792a06
            firewall_proxy.SetEnabledPorts(all_ports)
Packit 792a06
Packit 792a06
        for trust in self._new_trusts_to_add:
Packit 792a06
            # add the trust unless already added
Packit 792a06
            if not report_only:
Packit 792a06
                self._added_trusts.add(trust)
Packit 792a06
Packit 792a06
            msg = _("trust '%s' has been added to the list of trusts to be "
Packit 792a06
                    "added to the firewall" % trust)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
        if not report_only:
Packit 792a06
            all_trusts = list(self._add_trusts.union(set(firewall_proxy.Trusts)))
Packit 792a06
            firewall_proxy.SetTrusts(all_trusts)
Packit 792a06
Packit 792a06
        # now do the same for the services that should be excluded
Packit 792a06
Packit 792a06
        # add messages for the already excluded services
Packit 792a06
        for svc in self._removed_svcs:
Packit 792a06
            msg = _("service '%s' has been added to the list of services to be "
Packit 792a06
                    "removed from the firewall" % svc)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
Packit 792a06
        # services, that should be excluded
Packit 792a06
        self._new_services_to_remove = {
Packit 792a06
            svc for svc in self._remove_svcs
Packit 792a06
            if svc not in firewall_proxy.DisabledServices}
Packit 792a06
Packit 792a06
        for svc in self._new_services_to_remove:
Packit 792a06
            # exclude the service unless already excluded
Packit 792a06
            if not report_only:
Packit 792a06
                self._removed_svcs.add(svc)
Packit 792a06
Packit 792a06
            msg = _("service '%s' has been added to the list of services to be "
Packit 792a06
                    "removed from the firewall" % svc)
Packit 792a06
            messages.append(RuleMessage(self.__class__,
Packit 792a06
                                        common.MESSAGE_TYPE_INFO, msg))
Packit 792a06
        if not report_only:
Packit 792a06
            all_services = list(self._remove_svcs.union(set(firewall_proxy.DisabledServices)))
Packit 792a06
            firewall_proxy.SetDisabledServices(all_services)
Packit 792a06
Packit 792a06
        return messages
Packit 792a06
Packit 792a06
    def revert_changes(self, ksdata, storage):
Packit 792a06
        """:see: RuleHander.revert_changes"""
Packit 792a06
        firewall_proxy = NETWORK.get_proxy(FIREWALL)
Packit 792a06
Packit 792a06
        if self._firewall_enabled is not None:
Packit 792a06
            firewall_proxy.SetFirewallMode(self._firewall_default_state)
Packit 792a06
Packit 792a06
        # remove all services this handler added
Packit 792a06
        all_services = firewall_proxy.EnabledServices
Packit 792a06
        orig_services = set(all_services).difference(self._new_services_to_add)
Packit 792a06
        firewall_proxy.SetEnabledServices(list(orig_services))
Packit 792a06
Packit 792a06
        # remove all ports this handler added
Packit 792a06
        all_ports = firewall_proxy.EnabledPorts
Packit 792a06
        orig_ports = set(all_ports).difference(self._new_ports_to_add)
Packit 792a06
        firewall_proxy.SetEnabledPorts(list(orig_ports))
Packit 792a06
Packit 792a06
        # remove all trusts this handler added
Packit 792a06
        all_trusts = firewall_proxy.Trusts
Packit 792a06
        orig_trusts = set(all_trusts).difference(self._new_trusts_to_add)
Packit 792a06
        firewall_proxy.SetTrusts(list(orig_trusts))
Packit 792a06
Packit 792a06
        # remove all services this handler excluded
Packit 792a06
        all_services = firewall_proxy.DisabledServices
Packit 792a06
        orig_services = set(all_services).difference(self._new_services_to_remove)
Packit 792a06
        firewall_proxy.SetDisabledServices(list(orig_services))
Packit 792a06
Packit 792a06
        self._added_svcs = set()
Packit 792a06
        self._added_ports = set()
Packit 792a06
        self._added_trusts = set()
Packit 792a06
        self._removed_svcs = set()
Packit 792a06
        self._firewall_enabled = None
Packit 792a06
        self._firewall_default_state = None