|
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
|