From 5e7a6e648c85cf923093ebac6448be82ba032448 Mon Sep 17 00:00:00 2001
From: Vratislav Podzimek <vpodzime@redhat.com>
Date: Wed, 25 May 2016 10:58:54 +0200
Subject: [PATCH 06/13] Allow fixing root password in graphical installations
If the root password from kickstart is too short we can give users a chance to
enter a new (better) one in case of graphical installation. Text mode doesn't
allow for this because the root password configuration happens before the SCAP
content is evaluated.
Resolves: rhbz#1265116
---
org_fedora_oscap/common.py | 3 ++-
org_fedora_oscap/gui/spokes/oscap.py | 39 +++++++++++++++++++++++++++++++-----
org_fedora_oscap/rule_handling.py | 29 ++++++++++++++++-----------
3 files changed, 53 insertions(+), 18 deletions(-)
diff --git a/org_fedora_oscap/common.py b/org_fedora_oscap/common.py
index d09ccbd..8b2e84f 100644
--- a/org_fedora_oscap/common.py
+++ b/org_fedora_oscap/common.py
@@ -82,9 +82,10 @@ MESSAGE_TYPE_WARNING = 1
MESSAGE_TYPE_INFO = 2
# namedtuple for messages returned from the rules evaluation
+# origin -- class (inherited from RuleHandler) that generated the message
# type -- one of the MESSAGE_TYPE_* constants defined above
# text -- the actual message that should be displayed, logged, ...
-RuleMessage = namedtuple("RuleMessage", ["type", "text"])
+RuleMessage = namedtuple("RuleMessage", ["origin", "type", "text"])
def get_fix_rules_pre(profile, fpath, ds_id="", xccdf_id="", tailoring=""):
"""
diff --git a/org_fedora_oscap/gui/spokes/oscap.py b/org_fedora_oscap/gui/spokes/oscap.py
index 3b8dbd7..42fc406 100644
--- a/org_fedora_oscap/gui/spokes/oscap.py
+++ b/org_fedora_oscap/gui/spokes/oscap.py
@@ -200,6 +200,11 @@ class OSCAPSpoke(NormalSpoke):
# leaving the spoke
self._rule_data = None
+ # used for storing previously set root password if we need to remove it
+ # due to the chosen policy (so that we can put it back in case of
+ # revert)
+ self.__old_root_pw = None
+
# used to check if the profile was changed or not
self._active_profile = None
@@ -584,20 +589,43 @@ class OSCAPSpoke(NormalSpoke):
# no messages from the rules, add a message informing about that
if not self._active_profile:
# because of no profile
- message = common.RuleMessage(common.MESSAGE_TYPE_INFO,
- _("No profile selected"))
+ message = common.RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO,
+ _("No profile selected"))
else:
# because of no pre-inst rules
- message = common.RuleMessage(common.MESSAGE_TYPE_INFO,
- _("No rules for the pre-installation phase"))
+ message = common.RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO,
+ _("No rules for the pre-installation phase"))
self._add_message(message)
# nothing more to be done
return
+ self._resolve_rootpw_issues(messages, report_only)
for msg in messages:
self._add_message(msg)
+ def _resolve_rootpw_issues(self, messages, report_only):
+ """Mitigate root password issues (which are not fatal in GUI)"""
+ fatal_rootpw_msgs = [msg for msg in messages
+ if msg.origin == rule_handling.PasswdRules and msg.type == common.MESSAGE_TYPE_FATAL]
+ if fatal_rootpw_msgs:
+ for msg in fatal_rootpw_msgs:
+ # cannot just change the message type because it is a namedtuple
+ messages.remove(msg)
+ messages.append(common.RuleMessage(self.__class__, common.MESSAGE_TYPE_WARNING, msg.text))
+ if not report_only:
+ self.__old_root_pw = self.data.rootpw.password
+ self.data.rootpw.password = None
+ self.__old_root_pw_seen = self.data.rootpw.password.seen
+ self.data.rootpw.password.seen = False
+
+ def _revert_rootpw_changes(self):
+ if self.__old_root_pw is not None:
+ self.data.rootpw.password = self.__old_root_pw
+ self.data.rootpw.password.seen = self.__old_root_pw_seen
+ self.__old_root_pw = None
+ self.__old_root_pw_seen = None
+
@gtk_action_wait
def _unselect_profile(self, profile_id):
"""Unselects the given profile."""
@@ -615,6 +643,7 @@ class OSCAPSpoke(NormalSpoke):
if self._rule_data:
# revert changes and clear rule_data (no longer valid)
self._rule_data.revert_changes(self.data, self._storage)
+ self._revert_rootpw_changes()
self._rule_data = None
self._active_profile = None
@@ -769,7 +798,7 @@ class OSCAPSpoke(NormalSpoke):
# no messages in the dry-run mode
self._message_store.clear()
- message = common.RuleMessage(common.MESSAGE_TYPE_INFO,
+ message = common.RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO,
_("Not applying security policy"))
self._add_message(message)
diff --git a/org_fedora_oscap/rule_handling.py b/org_fedora_oscap/rule_handling.py
index a7bed22..2d58efe 100644
--- a/org_fedora_oscap/rule_handling.py
+++ b/org_fedora_oscap/rule_handling.py
@@ -223,6 +223,11 @@ class RuleData(RuleHandler):
if opts.passwd:
self._bootloader_rules.require_password()
+ @property
+ def passwd_rules(self):
+ # needed for fixups in GUI
+ return self._passwd_rules
+
class PartRules(RuleHandler):
"""Simple class holding data from the rules affecting partitioning."""
@@ -324,7 +329,7 @@ class PartRule(RuleHandler):
if self._mount_point not in storage.mountpoints:
msg = _("%s must be on a separate partition or logical "
"volume" % self._mount_point)
- messages.append(RuleMessage(common.MESSAGE_TYPE_FATAL, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_FATAL, msg))
# mount point doesn't exist, nothing more can be found here
return messages
@@ -337,7 +342,7 @@ class PartRule(RuleHandler):
for opt in self._added_mount_options:
msg = msg_tmpl % { "mount_option": opt,
"mount_point": self._mount_point }
- messages.append(RuleMessage(common.MESSAGE_TYPE_INFO, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# mount point to be created during installation
target_mount_point = storage.mountpoints[self._mount_point]
@@ -352,7 +357,7 @@ class PartRule(RuleHandler):
"mount_point": self._mount_point }
# add message for the mount option in any case
- messages.append(RuleMessage(common.MESSAGE_TYPE_INFO, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# add new options to the target mount point if not reporting only
if not report_only:
@@ -428,18 +433,18 @@ class PasswdRules(RuleHandler):
msg = _("make sure to create password with minimal length of %d "
"characters") % self._minlen
- ret = [RuleMessage(common.MESSAGE_TYPE_WARNING, msg)]
+ ret = [RuleMessage(self.__class__, common.MESSAGE_TYPE_WARNING, msg)]
else:
# root password set
if ksdata.rootpw.isCrypted:
msg = _("cannot check root password length (password is crypted)")
log.warning("cannot check root password length (password is crypted)")
- return [RuleMessage(common.MESSAGE_TYPE_WARNING, msg)]
+ return [RuleMessage(self.__class__, common.MESSAGE_TYPE_WARNING, msg)]
elif len(ksdata.rootpw.password) < self._minlen:
# too short
msg = _("root password is too short, a longer one with at "
"least %d characters is required") % self._minlen
- ret = [RuleMessage(common.MESSAGE_TYPE_FATAL, msg)]
+ ret = [RuleMessage(self.__class__, common.MESSAGE_TYPE_FATAL, msg)]
else:
ret = []
@@ -532,7 +537,7 @@ class PackageRules(RuleHandler):
for pkg in self._added_pkgs:
msg = _("package '%s' has been added to the list of to be installed "
"packages" % pkg)
- messages.append(RuleMessage(common.MESSAGE_TYPE_INFO, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# packages, that should be added
packages_to_add = (pkg for pkg in self._add_pkgs
@@ -546,7 +551,7 @@ class PackageRules(RuleHandler):
msg = _("package '%s' has been added to the list of to be installed "
"packages" % pkg)
- messages.append(RuleMessage(common.MESSAGE_TYPE_INFO, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
### now do the same for the packages that should be excluded
@@ -554,7 +559,7 @@ class PackageRules(RuleHandler):
for pkg in self._removed_pkgs:
msg = _("package '%s' has been added to the list of excluded "
"packages" % pkg)
- messages.append(RuleMessage(common.MESSAGE_TYPE_INFO, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
# packages, that should be added
packages_to_remove = (pkg for pkg in self._remove_pkgs
@@ -568,7 +573,7 @@ class PackageRules(RuleHandler):
msg = _("package '%s' has been added to the list of excluded "
"packages" % pkg)
- messages.append(RuleMessage(common.MESSAGE_TYPE_INFO, msg))
+ messages.append(RuleMessage(self.__class__, common.MESSAGE_TYPE_INFO, msg))
return messages
@@ -618,8 +623,8 @@ class BootloaderRules(RuleHandler):
# 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?
- return [RuleMessage(common.MESSAGE_TYPE_WARNING,
- "boot loader password not set up")]
+ return [RuleMessage(self.__class__, common.MESSAGE_TYPE_WARNING,
+ "boot loader password not set up")]
else:
return []
--
2.5.5