From 62d2e9832561d590fdcfbcab8bd03f5cb31fd5d1 Mon Sep 17 00:00:00 2001 From: Vratislav Podzimek Date: Wed, 25 May 2016 08:53:17 +0200 Subject: [PATCH 05/13] Enforce the minimal root password length With Anaconda supporting the pwpolicy command putting restrictions on (among the other things) root password minimal length we can actually enforce the policy given in the SCAP content in interactive installations. Resolves: rhbz#1238281 --- org_fedora_oscap/rule_handling.py | 50 ++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/org_fedora_oscap/rule_handling.py b/org_fedora_oscap/rule_handling.py index 6a67e8a..a7bed22 100644 --- a/org_fedora_oscap/rule_handling.py +++ b/org_fedora_oscap/rule_handling.py @@ -26,6 +26,8 @@ Module with various classes for handling pre-installation rules. import optparse import shlex +from pyanaconda.pwpolicy import F22_PwPolicyData + from org_fedora_oscap import common from org_fedora_oscap.common import OSCAPaddonError, RuleMessage @@ -35,6 +37,9 @@ __all__ = ["RuleData"] import gettext _ = lambda x: gettext.ldgettext("oscap-anaconda-addon", x) +import logging +log = logging.getLogger("anaconda") + # TODO: use set instead of list for mount options? def parse_csv(option, opt_str, value, parser): for item in value.split(","): @@ -392,6 +397,9 @@ class PasswdRules(RuleHandler): """Constructor initializing attributes.""" self._minlen = 0 + self._created_policy = False + self._orig_minlen = None + self._orig_strict = None def __str__(self): """Standard method useful for debugging and testing.""" @@ -414,25 +422,55 @@ class PasswdRules(RuleHandler): # no password restrictions, nothing to be done here return [] + ret = [] if not ksdata.rootpw.password: # root password was not set - # password length enforcement is not suported in the Anaconda yet msg = _("make sure to create password with minimal length of %d " - "characters" % self._minlen) - return [RuleMessage(common.MESSAGE_TYPE_WARNING, msg)] + "characters") % self._minlen + ret = [RuleMessage(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)] 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) - return [RuleMessage(common.MESSAGE_TYPE_FATAL, msg)] + "least %d characters is required") % self._minlen + ret = [RuleMessage(common.MESSAGE_TYPE_FATAL, msg)] else: - return [] + ret = [] + + # set the policy in any case (so that a weaker password is not entered) + pw_policy = ksdata.anaconda.pwpolicy.get_policy("root") + if pw_policy is None: + pw_policy = F22_PwPolicyData() + ksdata.anaconda.pwpolicy.policyList.append(pw_policy) + self._created_policy = True + + self._orig_minlen = pw_policy.minlen + self._orig_strict = pw_policy.strict + pw_policy.minlen = self._minlen + pw_policy.strict = True + + return ret + + def revert_changes(self, ksdata, storage): + """:see: RuleHander.revert_changes""" + + pw_policy = ksdata.anaconda.pwpolicy.get_policy("root") + if self._created_policy: + ksdata.anaconda.pwpolicy.policyList.remove(pw_policy) + self._created_policy = False + else: + if self._orig_minlen is not None: + pw_policy.minlen = self._orig_minlen + self._orig_minlen = None + if self._orig_strict is not None: + pw_policy.strict = self._orig_strict + self._orig_strict = None class PackageRules(RuleHandler): """Simple class holding data from the rules affecting installed packages.""" -- 2.5.5