示例#1
0
 def password_empty_test(self):
     """Check if quality of an empty password is reported correctly."""
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     self.assertEqual(check.result.password_score,
                      1)  # empty password is fine with emptyok policy
     self.assertEqual(check.result.status_text,
                      _(constants.PasswordStatus.EMPTY.value))
     self.assertEqual(check.result.password_quality, 0)
     self.assertIsNotNone(check.result.error_message)
     # empty password should override password-too-short messages
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.minlen = 10
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     self.assertEqual(check.result.password_score, 1)
     self.assertEqual(check.result.status_text,
                      _(constants.PasswordStatus.EMPTY.value))
     self.assertEqual(check.result.password_quality, 0)
     self.assertIsNotNone(check.result.error_message)
示例#2
0
 def password_empty_ok_test(self):
     """Check if the empty_ok flag works correctly."""
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.emptyok = True
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     self.assertEqual(check.result.password_score, 1)
     self.assertEqual(check.result.status_text,
                      _(constants.PasswordStatus.EMPTY.value))
     self.assertEqual(check.result.password_quality, 0)
     self.assertIsNotNone(check.result.error_message)
     # empty_ok with password length
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.emptyok = True
     request.policy.minlen = 10
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     self.assertEqual(check.result.password_score, 1)
     self.assertEqual(check.result.status_text,
                      _(constants.PasswordStatus.EMPTY.value))
     self.assertEqual(check.result.password_quality, 0)
     self.assertIsNotNone(check.result.error_message)
     # non-empty passwords that are too short should still get a score of 0 & the "too short" message
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.emptyok = True
     request.policy.minlen = 10
     request.password = "******"
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     self.assertEqual(check.result.password_score, 0)
     self.assertEqual(check.result.status_text,
                      _(constants.PasswordStatus.TOO_SHORT.value))
     self.assertEqual(check.result.password_quality, 0)
     self.assertIsNotNone(check.result.error_message)
     # also check a long-enough password, just in case
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.emptyok = True
     request.policy.minlen = 10
     request.password = "******"
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     self.assertEqual(check.result.password_score, 1)
     self.assertEqual(check.result.status_text,
                      _(constants.PasswordStatus.WEAK.value))
     self.assertEqual(check.result.password_quality, 0)
     self.assertIsNotNone(check.result.error_message)
 def test_password_empty_ok(self):
     """Check if the empty_ok flag works correctly."""
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.allow_empty = True
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     assert check.result.password_score == 1
     assert check.result.status_text == _(
         constants.SecretStatus.EMPTY.value)
     assert check.result.password_quality == 0
     assert check.result.error_message is not None
     # empty_ok with password length
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.allow_empty = True
     request.policy.min_length = 10
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     assert check.result.password_score == 1
     assert check.result.status_text == _(
         constants.SecretStatus.EMPTY.value)
     assert check.result.password_quality == 0
     assert check.result.error_message is not None
     # non-empty passwords that are too short should still get a score of 0 & the "too short" message
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.allow_empty = True
     request.policy.min_length = 10
     request.password = "******"
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     assert check.result.password_score == 0
     assert check.result.status_text == _(
         constants.SecretStatus.TOO_SHORT.value)
     assert check.result.password_quality == 0
     assert check.result.error_message is not None
     # also check a long-enough password, just in case
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.allow_empty = True
     request.policy.min_length = 10
     request.password = "******"
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     assert check.result.password_score == 1
     assert check.result.status_text == _(constants.SecretStatus.WEAK.value)
     assert check.result.password_quality == 0
     assert check.result.error_message is not None
示例#4
0
    def __init__(self, data, default_passphrase=""):
        super().__init__(data)

        self._passphrase_entry = self.builder.get_object("passphrase_entry")
        self._confirm_entry = self.builder.get_object("confirm_pw_entry")

        self._save_button = self.builder.get_object("passphrase_save_button")

        self._strength_bar = self.builder.get_object("strength_bar")
        self._strength_label = self.builder.get_object("strength_label")

        self._passphrase_warning_image = self.builder.get_object("passphrase_warning_image")
        self._passphrase_warning_label = self.builder.get_object("passphrase_warning_label")

        # Set the offset values for the strength bar colors
        self._strength_bar.add_offset_value("low", 2)
        self._strength_bar.add_offset_value("medium", 3)
        self._strength_bar.add_offset_value("high", 4)

        # Setup the password checker for passphrase checking
        self._checker = input_checking.PasswordChecker(
            initial_password_content=self._passphrase_entry.get_text(),
            initial_password_confirmation_content=self._confirm_entry.get_text(),
            policy_name=PASSWORD_POLICY_LUKS
        )

        # configure the checker for passphrase checking
        self._checker.secret_type = constants.SecretType.PASSPHRASE
        # connect UI updates to check results
        self._checker.checks_done.connect(self._set_status)

        self.passphrase = default_passphrase
        self._passphrase_good_enough = False

        # check that the content of the passphrase field & the conformation field are the same
        self._confirm_check = input_checking.PasswordConfirmationCheck()
        # check passphrase validity, quality and strength
        self._validity_check = input_checking.PasswordValidityCheck()
        # connect UI updates to validity check results
        self._validity_check.result.password_score_changed.connect(self._set_password_strength)
        self._validity_check.result.status_text_changed.connect(self._set_password_status_text)
        # check if the passphrase contains non-ascii characters
        self._ascii_check = input_checking.PasswordASCIICheck()
        # check if the passphrase is empty
        self._empty_check = input_checking.PasswordEmptyCheck()

        # register the individual checks with the checker in proper order
        # 1) are both entered passphrases the same ?
        # 2) is the passphrase valid according to the current password checking policy ?
        # 3) is the passphrase free of non-ASCII characters ?
        self._checker.add_check(self._confirm_check)
        self._checker.add_check(self._validity_check)
        self._checker.add_check(self._ascii_check)
        self._checker.add_check(self._empty_check)

        # set the visibility of the password entries
        # - without this the password visibility toggle icon will
        #   not be shown
        set_password_visibility(self._passphrase_entry, False)
        set_password_visibility(self._confirm_entry, False)
示例#5
0
    def _validate_password(self, password, confirm):
        """Validate and process user password."""
        if password != confirm:
            self._report(
                _(constants.SECRET_CONFIRM_ERROR_TUI[self._secret_type]))
            return None

        # If an empty password was provided, unset the value
        if not password:
            return ""

        # prepare a password validation request
        password_check_request = input_checking.PasswordCheckRequest()
        password_check_request.password = password
        password_check_request.password_confirmation = ""
        password_check_request.policy = self._policy

        # validate the password
        password_check = input_checking.PasswordValidityCheck()
        password_check.run(password_check_request)

        # if the score is equal to 0 and we have an error message set
        if not password_check.result.password_score and password_check.result.error_message:
            self._report(password_check.result.error_message)
            return None

        if password_check.result.password_quality < self._policy.min_quality:
            if self._policy.is_strict:
                done_msg = ""
            else:
                done_msg = _("\nWould you like to use it anyway?")

            if password_check.result.error_message:
                weak_prefix = _(
                    constants.SECRET_WEAK_WITH_ERROR[self._secret_type])
                error = "{} {} {}".format(weak_prefix,
                                          password_check.result.error_message,
                                          done_msg)
            else:
                weak_prefix = _(constants.SECRET_WEAK[self._secret_type])
                error = "{} {}".format(weak_prefix, done_msg)

            if not self._policy.is_strict:
                question_window = YesNoDialog(error)
                ScreenHandler.push_screen_modal(question_window)
                if not question_window.answer:
                    return None
            else:
                self._report(error)
                return None

        if any(char not in constants.PW_ASCII_CHARS for char in password):
            self._report(_(constants.SECRET_ASCII[self._secret_type]))

        return self._process_password(password)
示例#6
0
    def password_length_test(self):
        """Check if minimal password length is checked properly."""
        # first check if the default minimal password length is checked correctly
        # (should be 6 characters at the moment)
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertEqual(check.result.password_score, 0)
        self.assertEqual(check.result.status_text,
                         _(constants.PasswordStatus.TOO_SHORT.value))

        # weak but long enough
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertEqual(check.result.password_score, 1)
        self.assertEqual(check.result.status_text,
                         _(constants.PasswordStatus.WEAK.value))

        # check if setting password length works correctly
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.minlen = 10
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertEqual(check.result.password_score, 0)
        self.assertEqual(check.result.status_text,
                         _(constants.PasswordStatus.TOO_SHORT.value))
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.minlen = 10
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertGreater(check.result.password_score, 0)
        self.assertNotEqual(check.result.status_text,
                            _(constants.PasswordStatus.TOO_SHORT.value))
    def test_password_length(self):
        """Check if minimal password length is checked properly."""
        # first check if the default minimal password length is checked correctly
        # (should be 6 characters at the moment)
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score == 0
        assert check.result.status_text == _(
            constants.SecretStatus.TOO_SHORT.value)

        # weak but long enough
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score == 1
        assert check.result.status_text == _(constants.SecretStatus.WEAK.value)

        # check if setting password length works correctly
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.min_length = 10
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score == 0
        assert check.result.status_text == _(
            constants.SecretStatus.TOO_SHORT.value)
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.min_length = 10
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score > 0
        assert check.result.status_text != _(
            constants.SecretStatus.TOO_SHORT.value)
 def test_password_empty(self):
     """Check if quality of an empty password is reported correctly."""
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     assert check.result.password_score == 1  # empty password is fine with emptyok policy
     assert check.result.status_text == _(
         constants.SecretStatus.EMPTY.value)
     assert check.result.password_quality == 0
     assert check.result.error_message is not None
     # empty password should override password-too-short messages
     request = input_checking.PasswordCheckRequest()
     request.policy = get_policy()
     request.policy.min_length = 10
     request.password = ""
     check = input_checking.PasswordValidityCheck()
     check.run(request)
     assert check.result.password_score == 1
     assert check.result.status_text == _(
         constants.SecretStatus.EMPTY.value)
     assert check.result.password_quality == 0
     assert check.result.error_message is not None
示例#9
0
    def initialize(self):
        NormalSpoke.initialize(self)
        self.initialize_start()
        # get object references from the builders
        self._password_entry = self.builder.get_object("password_entry")
        self._password_confirmation_entry = self.builder.get_object("password_confirmation_entry")
        self._password_bar = self.builder.get_object("password_bar")
        self._password_label = self.builder.get_object("password_label")
        self._enable_root_radio = self.builder.get_object("enable_root_radio")
        self._disable_root_radio = self.builder.get_object("disable_root_radio")
        self._root_password_ssh_login_override = self.builder.get_object("root_password_ssh_login_override")
        self._revealer = self.builder.get_object("password_revealer")

        # Install the password checks:
        # - Has a password been specified?
        # - If a password has been specified and there is data in the confirm box, do they match?
        # - How strong is the password?
        # - Does the password contain non-ASCII characters?

        # Setup the password checker for password checking
        self._checker = input_checking.PasswordChecker(
                initial_password_content=self.password,
                initial_password_confirmation_content=self.password_confirmation,
                policy_name=PASSWORD_POLICY_ROOT
        )
        # configure the checker for password checking
        self.checker.secret_type = constants.SecretType.PASSWORD
        # remove any placeholder texts if either password or confirmation field changes content from initial state
        self.checker.password.changed_from_initial_state.connect(self.remove_placeholder_texts)
        self.checker.password_confirmation.changed_from_initial_state.connect(self.remove_placeholder_texts)
        # connect UI updates to check results
        self.checker.checks_done.connect(self._checks_done)

        # check that the password is not empty
        self._empty_check = input_checking.PasswordEmptyCheck()
        # check that the content of the password field & the conformation field are the same
        self._confirm_check = input_checking.PasswordConfirmationCheck()
        # check password validity, quality and strength
        self._validity_check = input_checking.PasswordValidityCheck()
        # connect UI updates to validity check results
        self._validity_check.result.password_score_changed.connect(self.set_password_score)
        self._validity_check.result.status_text_changed.connect(self.set_password_status)
        # check if the password contains non-ascii characters
        self._ascii_check = input_checking.PasswordASCIICheck()

        # register the individual checks with the checker in proper order
        # 1) is the password non-empty ?
        # 2) are both entered passwords the same ?
        # 3) is the password valid according to the current password checking policy ?
        # 4) is the password free of non-ASCII characters ?
        self.checker.add_check(self._empty_check)
        self.checker.add_check(self._confirm_check)
        self.checker.add_check(self._validity_check)
        self.checker.add_check(self._ascii_check)

        # Set placeholders if the password has been set outside of the Anaconda
        # GUI we either don't really know anything about it if it's crypted
        # and still would not really want to expose it if its set in plaintext,
        # and thus can'treally show it in the UI in any meaningful way.
        if self._users_module.IsRootPasswordSet:
            password_set_message = _("Root password has been set.")
            self.password_entry.set_placeholder_text(password_set_message)
            self.password_confirmation_entry.set_placeholder_text(password_set_message)

        # Configure levels for the password bar
        self._password_bar.add_offset_value("low", 2)
        self._password_bar.add_offset_value("medium", 3)
        self._password_bar.add_offset_value("high", 4)

        # set visibility of the password entries
        # - without this the password visibility toggle icon will
        #   not be shown
        set_password_visibility(self.password_entry, False)
        set_password_visibility(self.password_confirmation_entry, False)

        # Send ready signal to main event loop
        hubQ.send_ready(self.__class__.__name__)

        # report that we are done
        self.initialize_done()
示例#10
0
    def initialize(self):
        NormalSpoke.initialize(self)
        self.initialize_start()

        # Create a new UserData object to store this spoke's state
        # as well as the state of the advanced user dialog.
        if self.data.user.userList:
            self._user = copy.copy(self.data.user.userList[0])
        else:
            self._user = self.data.UserData()

        # gather references to relevant GUI objects

        # entry fields
        self._fullname_entry = self.builder.get_object("fullname_entry")
        self._username_entry = self.builder.get_object("username_entry")
        self._password_entry = self.builder.get_object("password_entry")
        self._password_confirmation_entry = self.builder.get_object(
            "password_confirmation_entry")
        # check boxes
        self._admin_checkbox = self.builder.get_object("admin_checkbox")
        self._password_required_checkbox = self.builder.get_object(
            "password_required_checkbox")
        # advanced user configration dialog button
        self._advanced_button = self.builder.get_object("advanced_button")
        # password checking status bar & label
        self._password_bar = self.builder.get_object("password_bar")
        self._password_label = self.builder.get_object("password_label")

        # Install the password checks:
        # - Has a password been specified?
        # - If a password has been specified and there is data in the confirm box, do they match?
        # - How strong is the password?
        # - Does the password contain non-ASCII characters?

        # Setup the password checker for password checking
        self._checker = input_checking.PasswordChecker(
            initial_password_content=self.password,
            initial_password_confirmation_content=self.password_confirmation,
            policy=input_checking.get_policy(self.data, "user"))
        # configure the checker for password checking
        self.checker.username = self.username
        self.checker.secret_type = constants.SecretType.PASSWORD
        # remove any placeholder texts if either password or confirmation field changes content from initial state
        self.checker.password.changed_from_initial_state.connect(
            self.remove_placeholder_texts)
        self.checker.password_confirmation.changed_from_initial_state.connect(
            self.remove_placeholder_texts)
        # connect UI updates to check results
        self.checker.checks_done.connect(self._checks_done)

        # username and full name checks
        self._username_check = input_checking.UsernameCheck()
        self._fullname_check = input_checking.FullnameCheck()
        # empty username is considered a success so that the user can leave
        # the spoke without filling it in
        self._username_check.success_if_username_empty = True
        # check that the password is not empty
        self._empty_check = input_checking.PasswordEmptyCheck()
        # check that the content of the password field & the conformation field are the same
        self._confirm_check = input_checking.PasswordConfirmationCheck()
        # check password validity, quality and strength
        self._validity_check = input_checking.PasswordValidityCheck()
        # connect UI updates to validity check results
        self._validity_check.result.password_score_changed.connect(
            self.set_password_score)
        self._validity_check.result.status_text_changed.connect(
            self.set_password_status)
        # check if the password contains non-ascii characters
        self._ascii_check = input_checking.PasswordASCIICheck()

        # register the individual checks with the checker in proper order
        # 0) is the username and fullname valid ?
        # 1) is the password non-empty ?
        # 2) are both entered passwords the same ?
        # 3) is the password valid according to the current password checking policy ?
        # 4) is the password free of non-ASCII characters ?
        self.checker.add_check(self._username_check)
        self.checker.add_check(self._fullname_check)
        self.checker.add_check(self._empty_check)
        self.checker.add_check(self._confirm_check)
        self.checker.add_check(self._validity_check)
        self.checker.add_check(self._ascii_check)

        self.guesser = {self.username_entry: True}

        # Configure levels for the password bar
        self.password_bar.add_offset_value("low", 2)
        self.password_bar.add_offset_value("medium", 3)
        self.password_bar.add_offset_value("high", 4)

        # indicate when the password was set by kickstart
        self.password_kickstarted = self.data.user.seen

        # Modify the GUI based on the kickstart and policy information
        # This needs to happen after the input checks have been created, since
        # the Gtk signal handlers use the input check variables.
        password_set_message = _("The password was set by kickstart.")
        if self.password_kickstarted:
            self.password_required = True
            self.password_entry.set_placeholder_text(password_set_message)
            self.password_confirmation_entry.set_placeholder_text(
                password_set_message)
        elif not self.checker.policy.emptyok:
            # Policy is that a non-empty password is required
            self.password_required = True

        if not self.checker.policy.emptyok:
            # User isn't allowed to change whether password is required or not
            self.password_required_checkbox.set_sensitive(False)

        self._advanced_user_dialog = AdvancedUserDialog(self._user, self.data)
        self._advanced_user_dialog.initialize()

        # set the visibility of the password entries
        set_password_visibility(self.password_entry, False)
        set_password_visibility(self.password_confirmation_entry, False)

        # report that we are done
        self.initialize_done()
示例#11
0
    def password_quality_test(self):
        """Check if libpwquality gives reasonable numbers & score is assigned correctly."""
        # " " should give score 0 (<6 chars) & quality 0
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertEqual(check.result.password_score, 0)
        self.assertEqual(check.result.status_text, _(constants.SecretStatus.TOO_SHORT.value))
        self.assertEqual(check.result.password_quality, 0)
        self.assertIsNotNone(check.result.error_message)

        # "anaconda" is a dictionary word
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertGreater(check.result.password_score, 0)
        self.assertNotEqual(check.result.status_text, _(constants.SecretStatus.EMPTY.value))
        self.assertNotEqual(check.result.status_text, _(constants.SecretStatus.TOO_SHORT.value))
        self.assertEqual(check.result.password_quality, 0)
        self.assertIsNotNone(check.result.error_message)

        # "jelenovipivonelej" is a palindrome
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertGreater(check.result.password_score, 0)
        self.assertNotEqual(check.result.status_text, _(constants.SecretStatus.EMPTY.value))
        self.assertNotEqual(check.result.status_text, _(constants.SecretStatus.TOO_SHORT.value))
        self.assertEqual(check.result.password_quality, 0)
        self.assertIsNotNone(check.result.error_message)

        # "4naconda-" gives a quality of 27 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertIs(check.result.error_message, "")

        # "4naconda----" gives a quality of 52 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertIs(check.result.error_message, "")

        # "----4naconda----" gives a quality of 80 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        self.assertIs(check.result.error_message, "")

        # "?----4naconda----?" gives a quality of 100 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)

        # this should (hopefully) give quality 100 everywhere
        self.assertEqual(check.result.password_score, 4)  # quality > 90
        self.assertEqual(check.result.status_text, _(constants.SecretStatus.STRONG.value))
        self.assertEqual(check.result.password_quality, 100)
        self.assertIs(check.result.error_message, "")

        # a long enough strong password with minlen set
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.minlen = 10
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        # this should (hopefully) give quality 100 everywhere
        self.assertEqual(check.result.password_score, 4)  # quality > 90
        self.assertEqual(check.result.status_text, _(constants.SecretStatus.STRONG.value))
        self.assertEqual(check.result.password_quality, 100)
        self.assertIs(check.result.error_message, "")

        # minimum password length overrides strong passwords for score and status
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.minlen = 30
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        # this should (hopefully) give quality 100 everywhere
        self.assertEqual(check.result.password_score, 0)  # too short
        self.assertEqual(check.result.status_text, _(constants.SecretStatus.TOO_SHORT.value))
        self.assertEqual(check.result.password_quality, 0)  # dependent on password length
        self.assertIs(check.result.error_message,
                      _(constants.SECRET_TOO_SHORT[constants.SecretType.PASSWORD]))
示例#12
0
    def initialize(self):
        NormalSpoke.initialize(self)
        self.initialize_start()
        # get object references from the builders
        self._password_entry = self.builder.get_object("password_entry")
        self._password_confirmation_entry = self.builder.get_object("password_confirmation_entry")
        self._password_bar = self.builder.get_object("password_bar")
        self._password_label = self.builder.get_object("password_label")

        # set state based on kickstart
        # NOTE: this will stop working once the module supports multiple kickstart commands
        self.password_kickstarted = self._users_module.proxy.IsRootpwKickstarted

        # Install the password checks:
        # - Has a password been specified?
        # - If a password has been specified and there is data in the confirm box, do they match?
        # - How strong is the password?
        # - Does the password contain non-ASCII characters?

        # Setup the password checker for password checking
        self._checker = input_checking.PasswordChecker(
                initial_password_content = self.password,
                initial_password_confirmation_content = self.password_confirmation,
                policy = input_checking.get_policy(self.data, "root")
        )
        # configure the checker for password checking
        self.checker.secret_type = constants.SecretType.PASSWORD
        # remove any placeholder texts if either password or confirmation field changes content from initial state
        self.checker.password.changed_from_initial_state.connect(self.remove_placeholder_texts)
        self.checker.password_confirmation.changed_from_initial_state.connect(self.remove_placeholder_texts)
        # connect UI updates to check results
        self.checker.checks_done.connect(self._checks_done)

        # check that the password is not empty
        self._empty_check = input_checking.PasswordEmptyCheck()
        # check that the content of the password field & the conformation field are the same
        self._confirm_check = input_checking.PasswordConfirmationCheck()
        # check password validity, quality and strength
        self._validity_check = input_checking.PasswordValidityCheck()
        # connect UI updates to validity check results
        self._validity_check.result.password_score_changed.connect(self.set_password_score)
        self._validity_check.result.status_text_changed.connect(self.set_password_status)
        # check if the password contains non-ascii characters
        self._ascii_check = input_checking.PasswordASCIICheck()

        # register the individual checks with the checker in proper order
        # 1) is the password non-empty ?
        # 2) are both entered passwords the same ?
        # 3) is the password valid according to the current password checking policy ?
        # 4) is the password free of non-ASCII characters ?
        self.checker.add_check(self._empty_check)
        self.checker.add_check(self._confirm_check)
        self.checker.add_check(self._validity_check)
        self.checker.add_check(self._ascii_check)

        # set placeholders if the password has been kickstarted as we likely don't know
        # nothing about it and can't really show it in the UI in any meaningful way
        password_set_message = _("The password was set by kickstart.")
        if self.password_kickstarted:
            self.password_entry.set_placeholder_text(password_set_message)
            self.password_confirmation_entry.set_placeholder_text(password_set_message)

        # Configure levels for the password bar
        self._password_bar.add_offset_value("low", 2)
        self._password_bar.add_offset_value("medium", 3)
        self._password_bar.add_offset_value("high", 4)

        # Send ready signal to main event loop
        hubQ.send_ready(self.__class__.__name__, False)

        # report that we are done
        self.initialize_done()
    def test_password_quality(self):
        """Check if libpwquality gives reasonable numbers & score is assigned correctly."""
        # " " should give score 0 (<6 chars) & quality 0
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score == 0
        assert check.result.status_text == _(
            constants.SecretStatus.TOO_SHORT.value)
        assert check.result.password_quality == 0
        assert check.result.error_message is not None

        # "anaconda" is a dictionary word
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score > 0
        assert check.result.status_text != _(
            constants.SecretStatus.EMPTY.value)
        assert check.result.status_text != _(
            constants.SecretStatus.TOO_SHORT.value)
        assert check.result.password_quality == 0
        assert check.result.error_message is not None

        # "jelenovipivonelej" is a palindrome
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.password_score > 0
        assert check.result.status_text != _(
            constants.SecretStatus.EMPTY.value)
        assert check.result.status_text != _(
            constants.SecretStatus.TOO_SHORT.value)
        assert check.result.password_quality == 0
        assert check.result.error_message is not None

        # "4naconda-" gives a quality of 27 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.error_message == ""

        # "4naconda----" gives a quality of 52 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.error_message == ""

        # "----4naconda----" gives a quality of 80 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        assert check.result.error_message == ""

        # "?----4naconda----?" gives a quality of 100 on RHEL7
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)

        # this should (hopefully) give quality 100 everywhere
        assert check.result.password_score == 4  # quality > 90
        assert check.result.status_text == _(
            constants.SecretStatus.STRONG.value)
        assert check.result.password_quality == 100
        assert check.result.error_message == ""

        # a long enough strong password with minlen set
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.min_length = 10
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        # this should (hopefully) give quality 100 everywhere
        assert check.result.password_score == 4  # quality > 90
        assert check.result.status_text == _(
            constants.SecretStatus.STRONG.value)
        assert check.result.password_quality == 100
        assert check.result.error_message == ""

        # minimum password length overrides strong passwords for score and status
        request = input_checking.PasswordCheckRequest()
        request.policy = get_policy()
        request.policy.min_length = 30
        request.password = "******"
        check = input_checking.PasswordValidityCheck()
        check.run(request)
        # this should (hopefully) give quality 100 everywhere
        assert check.result.password_score == 0  # too short
        assert check.result.status_text == _(
            constants.SecretStatus.TOO_SHORT.value)
        assert check.result.password_quality == 0  # dependent on password length
        assert check.result.error_message == \
            _(constants.SECRET_TOO_SHORT[constants.SecretType.PASSWORD])
示例#14
0
    def _validate_password(self, password, confirm):
        """Validate and process user password."""
        if (password and not confirm) or (confirm and not password):
            self._report(
                _("You must enter your root password and confirm it by typing"
                  " it a second time to continue."))
            return None
        if password != confirm:
            self._report(
                _(constants.PASSWORD_CONFIRM_ERROR_TUI) %
                {"password_name_plural": _(constants.NAME_OF_PASSWORD_PLURAL)})
            return None

        # If an empty password was provided, unset the value
        if not password:
            return ""

        # prepare a password validation request
        password_check_request = input_checking.PasswordCheckRequest()
        password_check_request.password = password
        password_check_request.password_confirmation = ""
        password_check_request.policy = self._policy

        # validate the password
        password_check = input_checking.PasswordValidityCheck()
        password_check.run(password_check_request)

        # if the score is equal to 0 and we have an error message set
        if not password_check.result.password_score and password_check.result.error_message:
            self._report(password_check.result.error_message)
            return None

        if password_check.result.password_quality < self._policy.minquality:
            if self._policy.strict:
                done_msg = ""
            else:
                done_msg = _("\nWould you like to use it anyway?")

            if password_check.result.error_message:
                error_prefix = _(constants.PASSWORD_WEAK_WITH_ERROR) % {
                    "password_name": _(constants.NAME_OF_PASSWORD),
                    "error_message": password_check.result.error_message
                }
                error = "{} {}".format(error_prefix, done_msg)
            else:
                weak_prefix = _(constants.PASSWORD_WEAK) % {
                    "password_name": _(constants.NAME_OF_PASSWORD)
                }
                error = "{} {}".format(weak_prefix, done_msg)

            if not self._policy.strict:
                question_window = YesNoDialog(error)
                ScreenHandler.push_screen_modal(question_window)
                if not question_window.answer:
                    return None
            else:
                self._report(error)
                return None

        if any(char not in constants.PW_ASCII_CHARS for char in password):
            self._report(
                _("You have provided a password containing non-ASCII characters.\n"
                  "You may not be able to switch between keyboard layouts to login.\n"
                  ))

        return cryptPassword(password)
示例#15
0
    def initialize(self):
        NormalSpoke.initialize(self)
        self.initialize_start()

        # We consider user creation requested if there was at least one user
        # in the DBus module user list at startup.
        # We also remember how the user was called so that we can clear it
        # in a reasonably safe way & if it was cleared.
        self._user_list = get_user_list(self._users_module, add_default=True)
        self._user_requested = False
        self._requested_user_cleared = False
        # if user has a name, it's an actual user that has been requested,
        # rather than a default user added by us
        if self.user.name:
            self._user_requested = True

        # gather references to relevant GUI objects

        # entry fields
        self._fullname_entry = self.builder.get_object("fullname_entry")
        self._username_entry = self.builder.get_object("username_entry")
        self._password_entry = self.builder.get_object("password_entry")
        self._password_confirmation_entry = self.builder.get_object("password_confirmation_entry")
        # check boxes
        self._admin_checkbox = self.builder.get_object("admin_checkbox")
        self._password_required_checkbox = self.builder.get_object("password_required_checkbox")
        # advanced user configration dialog button
        self._advanced_button = self.builder.get_object("advanced_button")
        # password checking status bar & label
        self._password_bar = self.builder.get_object("password_bar")
        self._password_label = self.builder.get_object("password_label")

        # Install the password checks:
        # - Has a password been specified?
        # - If a password has been specified and there is data in the confirm box, do they match?
        # - How strong is the password?
        # - Does the password contain non-ASCII characters?

        # Setup the password checker for password checking
        self._checker = input_checking.PasswordChecker(
                initial_password_content=self.password,
                initial_password_confirmation_content=self.password_confirmation,
                policy_name=PASSWORD_POLICY_USER
        )
        # configure the checker for password checking
        self.checker.username = self.username
        self.checker.secret_type = constants.SecretType.PASSWORD
        # remove any placeholder texts if either password or confirmation field changes content from initial state
        self.checker.password.changed_from_initial_state.connect(self.remove_placeholder_texts)
        self.checker.password_confirmation.changed_from_initial_state.connect(self.remove_placeholder_texts)
        # connect UI updates to check results
        self.checker.checks_done.connect(self._checks_done)

        # username and full name checks
        self._username_check = input_checking.UsernameCheck()
        self._fullname_check = input_checking.FullnameCheck()
        # empty username is considered a success so that the user can leave
        # the spoke without filling it in
        self._username_check.success_if_username_empty = True
        # check that the password is not empty
        self._empty_check = input_checking.PasswordEmptyCheck()
        # check that the content of the password field & the conformation field are the same
        self._confirm_check = input_checking.PasswordConfirmationCheck()
        # check password validity, quality and strength
        self._validity_check = input_checking.PasswordValidityCheck()
        # connect UI updates to validity check results
        self._validity_check.result.password_score_changed.connect(self.set_password_score)
        self._validity_check.result.status_text_changed.connect(self.set_password_status)
        # check if the password contains non-ascii characters
        self._ascii_check = input_checking.PasswordASCIICheck()
        # Skip the empty and validity password checks if no username is set
        self._empty_check.skip = True
        self._validity_check.skip = True

        # register the individual checks with the checker in proper order
        # 0) is the username and fullname valid ?
        # 1) is the password non-empty ?
        # 2) are both entered passwords the same ?
        # 3) is the password valid according to the current password checking policy ?
        # 4) is the password free of non-ASCII characters ?
        self.checker.add_check(self._username_check)
        self.checker.add_check(self._fullname_check)
        self.checker.add_check(self._empty_check)
        self.checker.add_check(self._confirm_check)
        self.checker.add_check(self._validity_check)
        self.checker.add_check(self._ascii_check)

        self.guesser = {
            self.username_entry: True
            }

        # Configure levels for the password bar
        self.password_bar.add_offset_value("low", 2)
        self.password_bar.add_offset_value("medium", 3)
        self.password_bar.add_offset_value("high", 4)

        # Modify the GUI based on the kickstart and policy information
        # This needs to happen after the input checks have been created, since
        # the Gtk signal handlers use the input check variables.
        password_set_message = _("The password was set by kickstart.")
        if self.password_kickstarted:
            self.password_required = True
            self.password_entry.set_placeholder_text(password_set_message)
            self.password_confirmation_entry.set_placeholder_text(password_set_message)
        elif not self.checker.policy.allow_empty:
            # Policy is that a non-empty password is required
            self.password_required = True

        if not self.checker.policy.allow_empty:
            # User isn't allowed to change whether password is required or not
            self.password_required_checkbox.set_sensitive(False)

        self._advanced_user_dialog = AdvancedUserDialog(self)
        self._advanced_user_dialog.initialize()

        # set the visibility of the password entries
        # - without this the password visibility toggle icon will
        #   not be shown
        set_password_visibility(self.password_entry, False)
        set_password_visibility(self.password_confirmation_entry, False)

        # report that we are done
        self.initialize_done()