Coverage for org_fedora_oscap/rule_handling.py : 68%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# # Copyright (C) 2013 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. You should have received a copy of the # GNU General Public License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # # Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com> #
Module with various classes for handling pre-installation rules.
"""
# everything else should be private
# TODO: use set instead of list for mount options?
"""Exception to be raised by ModifiedOptionParser."""
"""Overrides error behavior of OptionParser.""" raise ModifiedOptionParserException(msg)
raise ModifiedOptionParserException(msg)
action="callback", callback=parse_csv, nargs=1, type="string")
default=0, type="int")
type="string") type="string")
default=False)
dest="kdenabled", default=None) dest="kdenabled", default=None)
dest="fwenabled", default=None) dest="fwenabled", default=None) type="string") type="string") type="string") action="append", type="string")
"""Base class for the rule handlers."""
""" Method that should check the current state (as defined by the ksdata and storage parameters) against the rules the instance of RuleHandler holds. Depending on the value of report_only it should fix the state with changes that can be done automatically or not and return the list of warnings and errors for fixes that need to be done manually together with info messages about the automatic changes. One should make sure this method is called with report_only set to False at least once so that the automatic fixes are done.
:param ksdata: data representing the values set by user :type ksdata: pykickstart.base.BaseHandler :param storage: object storing storage-related information (disks, partitioning, bootloader, etc.) :type storage: blivet.Blivet :param report_only: whether to do fixing or just report information :type report_only: bool :return: errors and warnings for fixes that need to be done manually and info messages about the automatic changes :rtype: list of common.RuleMessage objects
"""
return []
""" Method that should revert all changes done by the previous calls of the eval_rules method with the report_only set to False.
:see: eval_rules
"""
# inheriting classes are supposed to override this
"""Exception class for cases when an uknown rule is to be processed."""
"""Class holding data parsed from the applied rules."""
"""Constructor initializing attributes."""
self._package_rules, self._bootloader_rules, self._kdump_rules, self._firewall_rules, )
"""Standard method useful for debugging and testing."""
ret = ""
part_strs = str(self._part_rules) if part_strs: ret += part_strs
passwd_str = str(self._passwd_rules) if passwd_str: ret += "\n" + passwd_str
packages_str = str(self._package_rules) if packages_str: ret += "\n" + packages_str
firewall_str = str(self._firewall_rules) if firewall_str: ret += "\n" + firewall_str
return ret
""" Method that handles a single rule line (e.g. "part /tmp").
:param rule: a single rule line :type rule: str
"""
"passwd": self._new_passwd_rule, "package": self._new_package_rule, "bootloader": self._new_bootloader_rule, "kdump": self._new_kdump_rule, "firewall": self._new_firewall_rule, }
except (ModifiedOptionParserException, KeyError) as e: log.warning("Unknown OSCAP Addon rule '{}': {}".format(rule, e))
""":see: RuleHandler.eval_rules"""
# evaluate all subgroups of rules
""":see: RuleHandler.revert_changes"""
# revert changes in all subgroups of rules
# args contain both "part" and mount point (e.g. "/tmp")
args = shlex.split(rule) (opts, args) = KDUMP_RULE_PARSER.parse_args(args)
self._kdump_rules.kdump_enabled(opts.kdenabled)
args = shlex.split(rule) (opts, args) = FIREWALL_RULE_PARSER.parse_args(args)
self._firewall_rules.add_services(opts.add_svcs) self._firewall_rules.remove_services(opts.remove_svcs) self._firewall_rules.add_trusts(opts.add_trust) self._firewall_rules.add_ports(opts.add_port) self._firewall_rules.firewall_enabled(opts.fwenabled)
def passwd_rules(self): # needed for fixups in GUI return self._passwd_rules
"""Simple class holding data from the rules affecting partitioning."""
"""Constructor initializing attributes."""
"""Standard method useful for debugging and testing."""
"""Method to support dictionary-like syntax."""
"""Method to support dictionary-like syntax."""
"""One of the methods needed to implement a container."""
"""One of the methods needed to implement a container."""
"""Method needed for the 'in' operator to work."""
""":see: RuleHandler.eval_rules"""
""":see: RuleHandler.revert_changes"""
"""Simple class holding rule data for a single partition/mount point."""
""" Constructor initializing attributes.
:param mount_point: the mount point the object holds data for :type mount_point: str
"""
"""Standard method useful for debugging and testing."""
""" Add new mount options (do not add duplicates).
:param mount_options: list of mount options to be added :type mount_options: list of strings
"""
if opt not in self._mount_options)
""":see: RuleHandler.eval_rules"""
"volume and has to be created in the " "partitioning layout before installation can occur " "with a security profile").format(self._mount_point) common.MESSAGE_TYPE_FATAL, msg))
# mount point doesn't exist, nothing more can be found here
# template for the message "the mount point %(mount_point)s")
# add message for every option already added "mount_point": self._mount_point} common.MESSAGE_TYPE_INFO, msg))
# mount point to be created during installation
# generator for the new options that should be added if opt not in target_mount_point.format.options.split(","))
# add message for every mount option added "mount_point": self._mount_point}
# add message for the mount option in any case common.MESSAGE_TYPE_INFO, msg))
# add new options to the target mount point if not reporting only
""" Removes the mount options added to the mount point by this PartRule instance.
:see: RuleHandler.revert_changes
"""
# mount point doesn't exist, nothing can be reverted
# mount point to be created during installation
# mount options to be defined for the created mount point
# generator of the options that should remain if opt not in self._added_mount_options)
# set the new list of options
# reset the remembered added mount options
"""Simple class holding data from the rules affecting passwords."""
"""Constructor initializing attributes."""
"""Standard method useful for debugging and testing."""
if self._minlen > 0: return "passwd --minlen=%d" % self._minlen else: return ""
"""Update password minimal length requirements."""
""":see: RuleHandler.eval_rules"""
# no password restrictions, nothing to be done here
# root password was not set
"characters") % self._minlen common.MESSAGE_TYPE_WARNING, msg)] else: # root password set common.MESSAGE_TYPE_WARNING, msg)] # too short "least %d characters is required") % self._minlen common.MESSAGE_TYPE_FATAL, msg)] else:
# set the policy in any case (so that a weaker password is not entered) pw_policy = F22_PwPolicyData() log.info("OSCAP addon: setting password policy %s" % pw_policy) ksdata.anaconda.pwpolicy.policyList.append(pw_policy) log.info("OSCAP addon: password policy list: %s" % ksdata.anaconda.pwpolicy.policyList) self._created_policy = True
""":see: RuleHander.revert_changes"""
log.info("OSCAP addon: removing password policy: %s" % pw_policy) ksdata.anaconda.pwpolicy.policyList.remove(pw_policy) log.info("OSCAP addon: password policy list: %s" % ksdata.anaconda.pwpolicy.policyList) self._created_policy = False else:
"""Simple class holding data from the rules affecting installed packages.
"""
"""Constructor setting the initial value of attributes."""
""" New packages that should be added.
:param packages: packages to be added :type packages: iterable
"""
""" New packages that should be removed.
:param packages: packages to be removed :type packages: iterable
"""
"""Standard method useful for debugging and testing."""
ret = "packages" adds = " ".join("--add=%s" % package for package in self._add_pkgs) if adds: ret += " " + adds
rems = " ".join("--remove=%s" % package for package in self._remove_pkgs) if rems: ret += " " + rems
return ret
""":see: RuleHandler.eval_rules"""
# add messages for the already added packages "packages" % pkg) common.MESSAGE_TYPE_INFO, msg))
# packages, that should be added if pkg not in ksdata.packages.packageList)
# add the package unless already added
"packages" % pkg) common.MESSAGE_TYPE_INFO, msg))
# now do the same for the packages that should be excluded
# add messages for the already excluded packages "packages" % pkg) common.MESSAGE_TYPE_INFO, msg))
# packages, that should be added if pkg not in ksdata.packages.excludedList)
# exclude the package unless already excluded
"packages" % pkg) common.MESSAGE_TYPE_INFO, msg))
""":see: RuleHander.revert_changes"""
# remove all packages this handler added
# remove all packages this handler excluded
"""Simple class holding data from the rules affecting bootloader."""
"""Constructor setting the initial value of attributes."""
"""Requests the bootloader password should be required."""
"""Standard method useful for debugging and testing."""
ret = "bootloader"
if self._require_password: ret += " --passwd"
return ret
""":see: RuleHandler.eval_rules"""
# Anaconda doesn't provide a way to set bootloader password, so # users cannot do much about that --> we shouldn't stop the # installation, should we? "boot loader password not set up")] else:
# nothing to be reverted for now
"""Simple class holding data from the rules affecting the kdump addon."""
"""Constructor setting the initial value of attributes."""
"""Enable or Disable Kdump"""
if kdenabled is not None: self._kdump_enabled = kdenabled
"""Standard method useful for debugging and testing."""
ret = "kdump"
if self._kdump_enabled is True: ret += " --enable"
if self._kdump_enabled is False: ret += " --disable"
return ret
""":see: RuleHandler.eval_rules"""
elif self._kdump_enabled is False: msg = _("Kdump will be disabled on startup") elif self._kdump_enabled is True: msg = _("Kdump will be enabled on startup")
messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
if not report_only: try: if self._kdump_default_enabled is None: # Kdump addon default startup setting self._kdump_default_enabled = ksdata.addons.com_redhat_kdump.enabled ksdata.addons.com_redhat_kdump.enabled = self._kdump_enabled except AttributeError: log.warning("com_redhat_kdump is not installed. " "Skipping kdump configuration")
return messages
""":see: RuleHander.revert_changes"""
ksdata.addons.com_redhat_kdump.enabled = self._kdump_default_enabled except AttributeError: log.warning("com_redhat_kdump is not installed. " "Skipping reverting kdump configuration")
"""Simple class holding data from the rules affecting firewall configurations."""
"""Constructor setting the initial value of attributes."""
""" Services that should be allowed through firewall.
:param services: services to be added :type services: iterable
"""
if services: self._add_svcs.update(services)
""" Ports that should be allowed through firewall.
:param ports: ports to be added :type ports: iterable
"""
if ports: self._add_ports.update(ports)
""" trusts that should be allowed through firewall.
:param trusts: trusts to be added :type trusts: iterable
"""
if trusts: self._add_trusts.update(trusts)
""" New services that should not be allowed through firewall.
:param services: services to be removed :type services: iterable
"""
if services: self._remove_svcs.update(services)
"""Enable or disable firewall"""
if fwenabled is not None: self._firewall_enabled = fwenabled
"""Standard method useful for debugging and testing."""
ret = "firewall"
if self._firewall_enabled is True: ret += " --enable"
if self._firewall_enabled is False: ret += " --disable"
adds = " ".join("--service=%s" % service for service in self._add_svcs) if adds: ret += " " + adds
rems = " ".join("--remove-service=%s" % service for service in self._remove_svcs) if rems: ret += " " + rems
ports = " ".join("--port=%s" % port for port in self._add_ports) if ports: ret += " " + ports
trusts = " ".join("--trust=%s" % trust for trust in self._add_trusts) if trusts: ret += " " + trusts
return ret
""":see: RuleHandler.eval_rules"""
# firewall default startup setting
msg = _("Firewall will be disabled on startup") messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg)) if not report_only: ksdata.firewall.enabled = self._firewall_enabled
msg = _("Firewall will be enabled on startup") messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg)) if not report_only: ksdata.firewall.enabled = self._firewall_enabled
# add messages for the already added services msg = _("service '%s' has been added to the list of services to be " "added to the firewall" % svc) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# add messages for the already added ports msg = _("port '%s' has been added to the list of ports to be " "added to the firewall" % port) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# add messages for the already added trusts msg = _("trust '%s' has been added to the list of trusts to be " "added to the firewall" % trust) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# services, that should be added if svc not in ksdata.firewall.services)
# ports, that should be added if ports not in ksdata.firewall.ports)
# trusts, that should be added if trust not in ksdata.firewall.trusts)
# add the service unless already added if not report_only: self._added_svcs.add(svc) ksdata.firewall.services.append(svc)
msg = _("service '%s' has been added to the list of services to be " "added to the firewall" % svc) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# add the port unless already added if not report_only: self._added_ports.add(port) ksdata.firewall.ports.append(port)
msg = _("port '%s' has been added to the list of ports to be " "added to the firewall" % port) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# add the trust unless already added if not report_only: self._added_trusts.add(trust) ksdata.firewall.trusts.append(trust)
msg = _("trust '%s' has been added to the list of trusts to be " "added to the firewall" % trust) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# now do the same for the services that should be excluded
# add messages for the already excluded services msg = _("service '%s' has been added to the list of services to be " "removed from the firewall" % svc) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# services, that should be added if svc not in ksdata.firewall.remove_services)
# exclude the service unless already excluded if not report_only: self._removed_svcs.add(svc) ksdata.firewall.remove_services.append(svc)
msg = _("service '%s' has been added to the list of services to be " "removed from the firewall" % svc) messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
""":see: RuleHander.revert_changes"""
ksdata.firewall.enabled = self._firewall_default_enabled
# remove all services this handler added if svc in ksdata.firewall.services: ksdata.firewall.services.remove(svc)
# remove all ports this handler added if port in ksdata.firewall.ports: ksdata.firewall.ports.remove(port)
# remove all trusts this handler added if trust in ksdata.firewall.trusts: ksdata.firewall.trusts.remove(trust)
# remove all services this handler excluded if svc in ksdata.firewall.remove_services: ksdata.firewall.remove_services.remove(svc)
|