def password_empty_ok_test(self): """Check if the empty_ok flag works correctly.""" score, status, quality, error_message = validatePassword("", empty_ok=True) self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # empty_ok with password length score, status, quality, error_message = validatePassword("", minlen=10, empty_ok=True) self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # non-empty passwords that are too short should still get a score of 0 & the "too short" message score, status, quality, error_message = validatePassword("123", minlen=10, empty_ok=True) self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # also check a long-enough password, just in case score, status, quality, error_message = validatePassword("1234567891", minlen=10, empty_ok=True) self.assertEqual(score, 1) self.assertEqual(status, _(constants.PasswordStatus.WEAK.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message)
def password_empty_test(self): """Check if quality of an empty password is reported correctly.""" score, status, quality, error_message = validatePassword("") self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # empty password should override password-too-short messages score, status, quality, error_message = validatePassword("", minlen=10) self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message)
def _updatePwQuality(self): """This method updates the password indicators according to the password entered by the user. """ pwtext = self.pw.get_text() username = self.username.get_text() # Reset the counters used for the "press Done twice" logic self._waiveStrengthClicks = 0 self._waiveASCIIClicks = 0 self._pwq_valid, strength, self._pwq_error = validatePassword(pwtext, username) if not pwtext: val = 0 elif strength < 50: val = 1 elif strength < 75: val = 2 elif strength < 90: val = 3 else: val = 4 text = _(PASSWORD_STRENGTH_DESC[val]) self.pw_bar.set_value(val) self.pw_label.set_text(text)
def prompt(self, entry=None): if not entry: return None if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) if (pw and not confirm) or (confirm and not pw): print(_("You must enter your root password and confirm it by typing" " it a second time to continue.")) return None if (pw != confirm): print(_(PASSWORD_CONFIRM_ERROR_TUI)) return None # If an empty password was provided, unset the value if not pw: self.value = "" return None valid, strength, message = validatePassword(pw, user=None, minlen=self.policy.minlen) if not valid: print(message) return None if strength < self.policy.minquality: if self.policy.strict: done_msg = "" else: done_msg = _("\nWould you like to use it anyway?") if message: error = _(PASSWORD_WEAK_WITH_ERROR) % message + " " + done_msg else: error = _(PASSWORD_WEAK) % done_msg if not self.policy.strict: question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None else: print(error) return None if any(char not in PW_ASCII_CHARS for char in pw): print(_("You have provided a password containing non-ASCII characters.\n" "You may not be able to switch between keyboard layouts to login.\n")) self.value = cryptPassword(pw) return None else: return tui.Prompt(_("Enter a new value for '%(title)s' and press %(enter)s") % { # TRANSLATORS: 'title' as a title of the entry "title": entry.title, # TRANSLATORS: 'enter' as the key ENTER "enter": tui.Prompt.ENTER })
def _validatePassword(self): # Do various steps to validate the password # sets self._error to an error string # Return True if valid, False otherwise self._error = False pw = self.pw.get_text() confirm = self.confirm.get_text() if not pw and not confirm: if self._kickstarted: return True else: self._error = _("You must provide and confirm a password.") return False try: self._error = validatePassword(pw, confirm) except PWQError as (e, msg): if pw == self._oldweak: # We got a second attempt with the same weak password pass else: self._error = _("You have provided a weak password: %s. " " Press Done again to use anyway.") % msg self._oldweak = pw return False
def prompt(self, entry): if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) error = None # just returning an error is either blank or mismatched # passwords. Raising is because of poor quality. try: error = validatePassword(pw, confirm) if error: print(error) return None strength = checkPassword(pw) if strength < 50: raise PWQError("The password you have provided is weak.") except PWQError as e: error = _("You have provided a weak password: %s. " % e.message) error += _("\nWould you like to use it anyway?") question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None self.value = cryptPassword(pw) return None else: return _( "Enter new value for '%s' and press enter\n") % entry.title
def _validatePassword(self): """This method checks the password weakness and implements the Press Done twice logic. It is used from the on_back_clicked handler. It also sets the self._error of the password is not sufficient or does not pass the pwquality checks. :return: True if the password should be accepted, False otherwise :rtype: bool """ # Do various steps to validate the password # sets self._error to an error string # Return True if valid, False otherwise self._error = False pw = self.pw.get_text() confirm = self.confirm.get_text() if not pw and not confirm: self._error = _("You must provide and confirm a password.") return False try: self._error = validatePassword(pw, confirm) except PWQError as (_e, msg): if pw == self._oldweak: # We got a second attempt with the same weak password pass else: self._error = _("You have provided a weak password: %s. " " Press Done again to use anyway.") % msg self._oldweak = pw return False
def _updatePwQuality(self, editable=None, data=None): """Update the password quality information. This function is called by the ::changed signal handler on the password field. """ pwtext = self.pw.get_text() # Reset the counter used for the "press Done twice" logic self._waivePasswordClicks = 0 self._pwq_valid, strength, self._pwq_error = validatePassword( pwtext, "root") if not pwtext: val = 0 elif strength < 50: val = 1 elif strength < 75: val = 2 elif strength < 90: val = 3 else: val = 4 text = _(PASSWORD_STRENGTH_DESC[val]) self.pw_bar.set_value(val) self.pw_label.set_text(text)
def _updatePwQuality(self): """This method updates the password indicators according to the password entered by the user. """ pwtext = self.pw.get_text() username = self.username.get_text() # Reset the counters used for the "press Done twice" logic self._waiveStrengthClicks = 0 self._waiveASCIIClicks = 0 self._pwq_valid, strength, self._pwq_error = validatePassword( pwtext, username) if not pwtext: val = 0 elif strength < 50: val = 1 elif strength < 75: val = 2 elif strength < 90: val = 3 else: val = 4 text = _(PASSWORD_STRENGTH_DESC[val]) self.pw_bar.set_value(val) self.pw_label.set_text(text)
def prompt(self, entry=None): if not entry: return None if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) if (pw and not confirm) or (confirm and not pw): print(_("You must enter your root password and confirm it by typing" " it a second time to continue.")) return None if pw != confirm: print(_(PASSWORD_CONFIRM_ERROR_TUI)) return None valid, strength, message = validatePassword(pw, user=None) if not valid: print(message) return None if strength < 50: if message: error = _("You have provided a weak password: %s\n" "Would you like to use it anyway?") % message else: error = _("You have provided a weak password.\n" "Would you like to use it anyway?") question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None self.value = cryptPassword(pw) return None else: return _("Enter new value for '%s' and press enter\n") % entry.title
def _updatePwQuality(self): """Update the password quality information. This function is called by the ::changed signal handler on the password field. """ pwtext = self.pw.get_text() # Reset the counters used for the "press Done twice" logic self._waiveStrengthClicks = 0 self._waiveASCIIClicks = 0 self._pwq_valid, strength, self._pwq_error = validatePassword(pwtext, "root", minlen=self.policy.minlen) if not pwtext: val = 0 elif strength < 50: val = 1 elif strength < 75: val = 2 elif strength < 90: val = 3 else: val = 4 text = _(PASSWORD_STRENGTH_DESC[val]) self.pw_bar.set_value(val) self.pw_label.set_text(text)
def prompt(self, entry=None): if not entry: return None if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) if (pw and not confirm) or (confirm and not pw): print(_("You must enter your root password and confirm it by typing" " it a second time to continue.")) return None if pw != confirm: print(_(PASSWORD_CONFIRM_ERROR_TUI)) return None # If an empty password was provided, unset the value if not pw: self.value = "" return None valid, strength, message = validatePassword(pw, user=None, minlen=self.policy.minlen) if not valid: print(message) return None if strength < self.policy.minquality: if self.policy.strict: done_msg = "" else: done_msg = _("\nWould you like to use it anyway?") if message: error = _(PASSWORD_WEAK_WITH_ERROR) % message + " " + done_msg else: error = _(PASSWORD_WEAK) % done_msg if not self.policy.strict: question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None else: print(error) return None if any(char not in PW_ASCII_CHARS for char in pw): print( _( "You have provided a password containing non-ASCII characters.\n" "You may not be able to switch between keyboard layouts to login.\n" ) ) self.value = cryptPassword(pw) return None else: return _("Enter a new value for '%s' and press <Enter>\n") % entry.title
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) score, status, _quality, _error_message = validatePassword("123") self.assertEqual(score, 0) self.assertEqual(_(status), _(constants.PasswordStatus.TOO_SHORT.value)) score, status, _quality, _error_message = validatePassword("123456") self.assertEqual(score, 1) self.assertEqual(_(status), _(constants.PasswordStatus.WEAK.value)) # check if setting password length works correctly score, status, _quality, _error_message = validatePassword("12345", minlen=10) self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) score, status, _quality, _error_message = validatePassword("1234567891", minlen=10) self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PasswordStatus.TOO_SHORT.value))
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. The password strength has already been checked in _updatePwQuality, called previously in the signal chain. This method converts the data set from there into an error message. The password strength check can be waived by pressing "Done" twice. This is controlled through the self._waiveStrengthClicks counter. The counter is set in on_back_clicked, which also re-runs this check manually. """ # Skip the check if no password is required if (not self.usepassword.get_active()) or \ ((not self.pw.get_text()) and (self._user.password_kickstarted)): return InputCheck.CHECK_OK # Check for validity errors # pw score == 0 & errors from libpwquality # - ignore if the strict flag in the password policy == False if not self._pw_score and self._pw_error_message and self.policy.strict: return self._pw_error_message # use strength from policy, not bars pw = self.pw.get_text() username = self.username.get_text() _pw_score, _status_text, pw_quality, _error_message = validatePassword( pw, username, minlen=self.policy.minlen, empty_ok=self.policy.emptyok) if pw_quality < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if self._pw_error_message: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR ) % self._pw_error_message else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if self._pw_error_message: return _(PASSWORD_WEAK_WITH_ERROR ) % self._pw_error_message + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
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) score, status, _quality, _error_message = validatePassword("123") self.assertEqual(score, 0) self.assertEqual(status, _(constants.PASSWORD_STATUS_TOO_SHORT)) score, status, _quality, _error_message = validatePassword("123456") self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PASSWORD_STATUS_EMPTY)) self.assertNotEqual(status, _(constants.PASSWORD_STATUS_TOO_SHORT)) # check if setting password length works correctly score, status, _quality, _error_message = validatePassword("12345", minlen=10) self.assertEqual(score, 0) self.assertEqual(status, _(constants.PASSWORD_STATUS_TOO_SHORT)) score, status, _quality, _error_message = validatePassword( "1234567891", minlen=10) self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PASSWORD_STATUS_TOO_SHORT))
def check_user_password_strength(self, inputcheck): """Update the error message based on password strength. The password strength check can be waived by pressing "Done" twice. This is controlled through the self.waive_clicks counter. The counter is set in on_back_clicked, which also re-runs this check manually. """ pw = self.input # Don't run any check if the password is empty - there is a dedicated check for that if not pw: return InputCheck.CHECK_OK # determine the password strength # pylint: disable=no-member pw_check_result = validatePassword(pw, self.input_username, minlen=self.policy.minlen, empty_ok=self.policy.emptyok) pw_score, status_text, pw_quality, error_message = pw_check_result self.set_input_score(pw_score) self.set_input_status(status_text) # Skip the check if no password is required if not self.input_enabled or self.input_kickstarted: return InputCheck.CHECK_OK # pylint: disable=no-member if pw_quality < self.policy.minquality or not pw_score or not pw: # If Done has been clicked twice, waive the check if self.waive_clicks > 1: return InputCheck.CHECK_OK elif self.waive_clicks == 1: if error_message: return _(constants.PASSWORD_WEAK_CONFIRM_WITH_ERROR ) % error_message else: return _(constants.PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice # pylint: disable=no-member if self.policy.strict: done_msg = "" else: done_msg = _(constants.PASSWORD_DONE_TWICE) if error_message: return _(constants.PASSWORD_WEAK_WITH_ERROR ) % error_message + " " + done_msg else: return _(constants.PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. The password strength check can be waived by pressing "Done" twice. This is controlled through the self._waiveStrengthClicks counter. The counter is set in on_back_clicked, which also re-runs this check manually. """ # Skip the check if no password is required if not self.usepassword.get_active or self._password_kickstarted: return InputCheck.CHECK_OK # If the password is empty, clear the strength bar and skip this check pw = self.pw.get_text() if not pw: self._updatePwQuality(True, 0) return InputCheck.CHECK_OK # determine the password strength username = self.username.get_text() valid, pwstrength, error = validatePassword(pw, username, minlen=self.policy.minlen) # set the strength bar self._updatePwQuality(False, pwstrength) # If the password failed the validity check, fail this check if not valid and error: return error if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if error: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % error else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if error: return _(PASSWORD_WEAK_WITH_ERROR) % error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. Update the password strength bar and set an error message. """ pw = self.pw.get_text() confirm = self.confirm.get_text() # Skip the check if no password is required if self._kickstarted: return InputCheck.CHECK_OK # If the password is empty, clear the strength bar and skip this check if self.lock.get_active() or (not pw and not confirm): self._updatePwQuality(True, 0) return InputCheck.CHECK_OK # determine the password strength valid, pwstrength, error = validatePassword(pw, "root", minlen=self.policy.minlen) # set the strength bar self._updatePwQuality(False, pwstrength) # If the password failed the validity check, fail this check if not valid and error: return error if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if error: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % error else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if error: return _(PASSWORD_WEAK_WITH_ERROR) % error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def check_user_password_strength(self, inputcheck): """Update the error message based on password strength. The password strength check can be waived by pressing "Done" twice. This is controlled through the self.waive_clicks counter. The counter is set in on_back_clicked, which also re-runs this check manually. """ pw = self.input # Don't run any check if the password is empty - there is a dedicated check for that if not pw: return InputCheck.CHECK_OK # determine the password strength # pylint: disable=no-member pw_check_result = validatePassword(pw, self.input_username, minlen=self.policy.minlen, empty_ok=self.policy.emptyok) pw_score, status_text, pw_quality, error_message = pw_check_result self.set_input_score(pw_score) self.set_input_status(status_text) # Skip the check if no password is required if not self.input_enabled or self.input_kickstarted: return InputCheck.CHECK_OK # pylint: disable=no-member if pw_quality < self.policy.minquality or not pw_score or not pw: # If Done has been clicked twice, waive the check if self.waive_clicks > 1: return InputCheck.CHECK_OK elif self.waive_clicks == 1: if error_message: return _(constants.PASSWORD_WEAK_CONFIRM_WITH_ERROR) % error_message else: return _(constants.PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice # pylint: disable=no-member if self.policy.strict: done_msg = "" else: done_msg = _(constants.PASSWORD_DONE_TWICE) if error_message: return _(constants.PASSWORD_WEAK_WITH_ERROR) % error_message + " " + done_msg else: return _(constants.PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. Convert the strength set by _updatePwQuality into an error message. """ pw = self.pw.get_text() confirm = self.confirm.get_text() # Skip the check if no password is required if (not pw and not confirm) and self._kickstarted: return InputCheck.CHECK_OK # Check for validity errors # pw score == 0 & errors from libpwquality # - ignore if the strict flag in the password policy == False if not self._pw_score and self._pw_error_message and self.policy.strict: return self._pw_error_message # use strength from policy, not bars _pw_score, _status_text, pw_quality, _error_message = validatePassword( pw, "root", minlen=self.policy.minlen, empty_ok=self.policy.emptyok) if pw_quality < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if self._pw_error_message: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR ) % self._pw_error_message else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if self._pw_error_message: return _(PASSWORD_WEAK_WITH_ERROR ) % self._pw_error_message + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. Update the password strength bar and set an error message. """ pw = self.pw.get_text() confirm = self.confirm.get_text() # Skip the check if no password is required if self._kickstarted: return InputCheck.CHECK_OK # If the password is empty, clear the strength bar and skip this check if not pw and not confirm: self._updatePwQuality(True, 0) return InputCheck.CHECK_OK # determine the password strength valid, pwstrength, error = validatePassword(pw, "root", minlen=self.policy.minlen) # set the strength bar self._updatePwQuality(False, pwstrength) # If the password failed the validity check, fail this check if not valid and error: return error if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if error: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % error else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if error: return _(PASSWORD_WEAK_WITH_ERROR) % error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. The password strength has already been checked in _updatePwQuality, called previously in the signal chain. This method converts the data set from there into an error message. The password strength check can be waived by pressing "Done" twice. This is controlled through the self._waiveStrengthClicks counter. The counter is set in on_back_clicked, which also re-runs this check manually. """ # Skip the check if no password is required if (not self.usepassword.get_active()) or \ ((not self.pw.get_text()) and (self._user.password_kickstarted)): return InputCheck.CHECK_OK # If the password failed the validity check, fail this check if (not self._pwq_valid) and (self._pwq_error): return self._pwq_error # use strength from policy, not bars pw = self.pw.get_text() username = self.username.get_text() _valid, pwstrength, _error = validatePassword(pw, username, minlen=self.policy.minlen) if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if self._pwq_error: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % self._pwq_error else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if self._pwq_error: return _(PASSWORD_WEAK_WITH_ERROR) % self._pwq_error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
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(_(PASSWORD_CONFIRM_ERROR_TUI)) return None # If an empty password was provided, unset the value if not password: return "" pw_score, _status_text, pw_quality, error_message = validatePassword(password, user=None, minlen=self._policy.minlen) # if the score is equal to 0 and we have an error message set if not pw_score and error_message: self._report(error_message) return None if pw_quality < self._policy.minquality: if self._policy.strict: done_msg = "" else: done_msg = _("\nWould you like to use it anyway?") if error_message: error = _(PASSWORD_WEAK_WITH_ERROR) % error_message + " " + done_msg else: error = _(PASSWORD_WEAK) % 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 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)
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. Convert the strength set by _updatePwQuality into an error message. """ pw = self.pw.get_text() confirm = self.confirm.get_text() # Skip the check if no password is required if (not pw and not confirm) and self._kickstarted: return InputCheck.CHECK_OK # Check for validity errors if (not self._pwq_valid) and (self._pwq_error): return self._pwq_error # use strength from policy, not bars _valid, pwstrength, _error = validatePassword( pw, "root", minlen=self.policy.minlen) if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if self._pwq_error: return _( PASSWORD_WEAK_CONFIRM_WITH_ERROR) % self._pwq_error else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if self._pwq_error: return _(PASSWORD_WEAK_WITH_ERROR ) % self._pwq_error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _updatePwQuality(self): """This method updates the password indicators according to the password entered by the user. """ pwtext = self.pw.get_text() username = self.username.get_text() # Reset the counters used for the "press Done twice" logic self._waiveStrengthClicks = 0 self._waiveASCIIClicks = 0 self._pw_score, status_text, _pw_quality, self._pw_error_message = validatePassword( pwtext, username, minlen=self.policy.minlen, empty_ok=self.policy.emptyok) self.pw_bar.set_value(self._pw_score) self.pw_label.set_text(status_text)
def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength. Convert the strength set by _updatePwQuality into an error message. """ pw = self.pw.get_text() confirm = self.confirm.get_text() # Skip the check if no password is required if (not pw and not confirm) and self._kickstarted: return InputCheck.CHECK_OK # Check for validity errors if (not self._pwq_valid) and (self._pwq_error): return self._pwq_error # use strength from policy, not bars _valid, pwstrength, _error = validatePassword(pw, "root", minlen=self.policy.minlen) if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: if self._pwq_error: return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % self._pwq_error else: return _(PASSWORD_WEAK_CONFIRM) else: # non-strict allows done to be clicked twice if self.policy.strict: done_msg = "" else: done_msg = _(PASSWORD_DONE_TWICE) if self._pwq_error: return _(PASSWORD_WEAK_WITH_ERROR) % self._pwq_error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: return InputCheck.CHECK_OK
def _updatePwQuality(self, editable=None, data=None): """Update the password quality information. This function is called by the ::changed signal handler on the password field. """ pwtext = self.pw.get_text() # Reset the counters used for the "press Done twice" logic self._waiveStrengthClicks = 0 self._waiveASCIIClicks = 0 self._pw_score, status_text, _pw_quality, self._pw_error_message = validatePassword( pwtext, "root", minlen=self.policy.minlen, empty_ok=self.policy.emptyok) self.pw_bar.set_value(self._pw_score) self.pw_label.set_text(status_text)
def prompt(self, entry=None): if not entry: return None if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) if (pw and not confirm) or (confirm and not pw): print( _("You must enter your root password and confirm it by typing" " it a second time to continue.")) return None if (pw != confirm): print(_(PASSWORD_CONFIRM_ERROR_TUI)) return None valid, strength, message = validatePassword(pw, user=None) if not valid: print(message) return None if strength < 50: if message: error = _("You have provided a weak password: %s\n" "Would you like to use it anyway?") % message else: error = _("You have provided a weak password.\n" "Would you like to use it anyway?") question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None self.value = cryptPassword(pw) return None else: return _( "Enter new value for '%s' and press enter\n") % entry.title
def prompt(self, entry): if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) error = None # just returning an error is either blank or mismatched # passwords. Raising is because of poor quality. try: error = validatePassword(pw, confirm) if error: print(error) return None except PWQError as (e, msg): error = _("You have provided a weak password: %s. " % msg) error += _("\nWould you like to use it anyway?") question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None self.value = pw return None
def password_quality_test(self): """Check if libpwquality gives reasonable numbers & score is assigned correctly.""" # " " should give score 0 (<6 chars) & quality 0 score, status, quality, error_message = validatePassword(" ") self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # "anaconda" is a dictionary word score, status, quality, error_message = validatePassword("anaconda") self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertNotEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # "jelenovipivonelej" is a palindrome score, status, quality, error_message = validatePassword("jelenovipivonelej") self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertNotEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # "4naconda-" gives a quality of 27 on RHEL7 score, status, quality, error_message = validatePassword("4naconda-") if ON_RHEL: self.assertEqual(score, 1) # quality < 50 self.assertEqual(status, _(constants.PasswordStatus.WEAK.value)) self.assertEqual(quality, 27) self.assertIsNone(error_message) # "4naconda----" gives a quality of 52 on RHEL7 score, status, quality, error_message = validatePassword("4naconda----") if ON_RHEL: self.assertEqual(score, 2) # quality > 50 & < 75 self.assertEqual(status, _(constants.PasswordStatus.FAIR.value)) self.assertEqual(quality, 52) self.assertIsNone(error_message) # "----4naconda----" gives a quality of 80 on RHEL7 score, status, quality, error_message = validatePassword("----4naconda----") if ON_RHEL: self.assertEqual(score, 3) # quality > 75 & < 90 self.assertEqual(status, _(constants.PasswordStatus.GOOD.value)) self.assertEqual(quality, 80) self.assertIsNone(error_message) # "?----4naconda----?" gives a quality of 100 on RHEL7 score, status, quality, error_message = validatePassword("?----4naconda----?") # this should (hopefully) give quality 100 everywhere self.assertEqual(score, 4) # quality > 90 self.assertEqual(status, _(constants.PasswordStatus.STRONG.value)) self.assertEqual(quality, 100) self.assertIsNone(error_message) # a long enough strong password with minlen set score, status, quality, error_message = validatePassword("?----4naconda----?", minlen=10) # this should (hopefully) give quality 100 everywhere self.assertEqual(score, 4) # quality > 90 self.assertEqual(status, _(constants.PasswordStatus.STRONG.value)) self.assertEqual(quality, 100) self.assertIsNone(error_message) # minimum password length overrides strong passwords for score and status score, status, quality, error_message = validatePassword("?----4naconda----?", minlen=30) # this should (hopefully) give quality 100 everywhere self.assertEqual(score, 0) # too short self.assertEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 100) # independent on password length self.assertIsNone(error_message)
def prompt(self, args=None): entry = args if not entry: return None if entry.aux == self.PASSWORD: pw = self.get_user_input(_("%s: ") % entry.title, hidden=True) confirm = self.get_user_input(_("%s (confirm): ") % entry.title, hidden=True) if (pw and not confirm) or (confirm and not pw): print(_("You must enter your root password and confirm it by typing" " it a second time to continue.")) return None if pw != confirm: print(_(PASSWORD_CONFIRM_ERROR_TUI)) return None # If an empty password was provided, unset the value if not pw: self.value = "" return None pw_score, _status_text, pw_quality, error_message = validatePassword(pw, user=None, minlen=self.policy.minlen) # if the score is equal to 0 and we have an error message set if not pw_score and error_message: print(error_message) return None if pw_quality < self.policy.minquality: if self.policy.strict: done_msg = "" else: done_msg = _("\nWould you like to use it anyway?") if error_message: error = _(PASSWORD_WEAK_WITH_ERROR) % error_message + " " + done_msg else: error = _(PASSWORD_WEAK) % 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: print(error) return None if any(char not in PW_ASCII_CHARS for char in pw): print(_("You have provided a password containing non-ASCII characters.\n" "You may not be able to switch between keyboard layouts to login.\n")) self.value = cryptPassword(pw) return None else: return Prompt(_("Enter a new value for '%(title)s' and press %(enter)s") % { # TRANSLATORS: 'title' as a title of the entry "title": entry.title, # TRANSLATORS: 'enter' as the key ENTER "enter": Prompt.ENTER })
def password_quality_test(self): """Check if libpwquality gives reasonable numbers & score is assigned correctly.""" # " " should give score 0 (<6 chars) & quality 0 score, status, quality, error_message = validatePassword(" ") self.assertEqual(score, 0) self.assertEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # "anaconda" is a dictionary word score, status, quality, error_message = validatePassword("anaconda") self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertNotEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # "jelenovipivonelej" is a palindrome score, status, quality, error_message = validatePassword( "jelenovipivonelej") self.assertGreater(score, 0) self.assertNotEqual(status, _(constants.PasswordStatus.EMPTY.value)) self.assertNotEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 0) self.assertIsNotNone(error_message) # "4naconda-" gives a quality of 27 on RHEL7 score, status, quality, error_message = validatePassword("4naconda-") if ON_RHEL: self.assertEqual(score, 1) # quality < 50 self.assertEqual(status, _(constants.PasswordStatus.WEAK.value)) self.assertEqual(quality, 27) self.assertIsNone(error_message) # "4naconda----" gives a quality of 52 on RHEL7 score, status, quality, error_message = validatePassword( "4naconda----") if ON_RHEL: self.assertEqual(score, 2) # quality > 50 & < 75 self.assertEqual(status, _(constants.PasswordStatus.FAIR.value)) self.assertEqual(quality, 52) self.assertIsNone(error_message) # "----4naconda----" gives a quality of 80 on RHEL7 score, status, quality, error_message = validatePassword( "----4naconda----") if ON_RHEL: self.assertEqual(score, 3) # quality > 75 & < 90 self.assertEqual(status, _(constants.PasswordStatus.GOOD.value)) self.assertEqual(quality, 80) self.assertIsNone(error_message) # "?----4naconda----?" gives a quality of 100 on RHEL7 score, status, quality, error_message = validatePassword( "?----4naconda----?") # this should (hopefully) give quality 100 everywhere self.assertEqual(score, 4) # quality > 90 self.assertEqual(status, _(constants.PasswordStatus.STRONG.value)) self.assertEqual(quality, 100) self.assertIsNone(error_message) # a long enough strong password with minlen set score, status, quality, error_message = validatePassword( "?----4naconda----?", minlen=10) # this should (hopefully) give quality 100 everywhere self.assertEqual(score, 4) # quality > 90 self.assertEqual(status, _(constants.PasswordStatus.STRONG.value)) self.assertEqual(quality, 100) self.assertIsNone(error_message) # minimum password length overrides strong passwords for score and status score, status, quality, error_message = validatePassword( "?----4naconda----?", minlen=30) # this should (hopefully) give quality 100 everywhere self.assertEqual(score, 0) # too short self.assertEqual(status, _(constants.PasswordStatus.TOO_SHORT.value)) self.assertEqual(quality, 100) # independent on password length self.assertIsNone(error_message)
def prompt(self, entry=None): if not entry: return None if entry.aux == self.PASSWORD: pw = self._app.raw_input(_("%s: ") % entry.title, hidden=True) confirm = self._app.raw_input(_("%s (confirm): ") % entry.title, hidden=True) if (pw and not confirm) or (confirm and not pw): print( _("You must enter your root password and confirm it by typing" " it a second time to continue.")) return None if (pw != confirm): print(_(PASSWORD_CONFIRM_ERROR_TUI)) return None # If an empty password was provided, unset the value if not pw: self.value = "" return None pw_score, _status_text, pw_quality, error_message = validatePassword( pw, user=None, minlen=self.policy.minlen) # if the score is equal to 0 and we have an error message set # - ignore if the strict flag in the password policy == False if not pw_score and error_message and self.policy.strict: print(error_message) return None if pw_quality < self.policy.minquality: if self.policy.strict: done_msg = "" else: done_msg = _("\nWould you like to use it anyway?") if error_message: error = _(PASSWORD_WEAK_WITH_ERROR ) % error_message + " " + done_msg else: error = _(PASSWORD_WEAK) % done_msg if not self.policy.strict: question_window = YesNoDialog(self._app, error) self._app.switch_screen_modal(question_window) if not question_window.answer: return None else: print(error) return None if any(char not in PW_ASCII_CHARS for char in pw): print( _("You have provided a password containing non-ASCII characters.\n" "You may not be able to switch between keyboard layouts to login.\n" )) self.value = cryptPassword(pw) return None else: return _( "Enter new value for '%s' and press enter\n") % entry.title