def ValidatePassword(password, username=None, dictpath=None): pwqs = pwquality.PWQSettings() pwqs.difok = min(5, (min(len(username), len(password)) + 1) / 2) pwqs.minlen = 8 pwqs.ucredit = 0 pwqs.lcredit = 0 pwqs.dcredit = 0 pwqs.ocredit = 0 pwqs.minclass = 3 pwqs.dictpath = dictpath try: try: pwqs.check(password, username, None) except pwquality.PWQError as e: if e.args[0] == -9: pwquality.PWQSettings().check('12345678', None, '12345678') elif e.args[0] == -22 and dictpath is None: pass else: raise except pwquality.PWQError as e: raise ValueError(e.args[1].lower()) return password
def validatePassword(pw, confirm, minlen=6): # Do various steps to validate the password # Return an error string, or None for no errors # If inital checks pass, pwquality will be tested. Raises # from pwquality will pass up to the calling code # if both pw and confirm are blank, password is disabled. if (pw and not confirm) or (confirm and not pw): error = _("You must enter your root password " "and confirm it by typing it a second " "time to continue.") return error if pw != confirm: error = _("The passwords you entered were " "different. Please try again.") return error legal = string.digits + string.ascii_letters + string.punctuation + " " for letter in pw: if letter not in legal: error = _("Requested password contains " "non-ASCII characters, which are " "not allowed.") return error if pw: settings = pwquality.PWQSettings() settings.read_config() settings.minlen = minlen settings.check(pw, None, "root") return None
def checkPassword(pw): """ Check the quality of a password passed in and return a numeric value. """ pwq = pwquality.PWQSettings() pwq.read_config() return pwq.check(pw, None, None)
def refresh(self): super(PassphraseDialog, self).refresh() # disable input methods for the passphrase Entry widgets self._passphrase_entry.set_property("im-module", "") self._confirm_entry.set_property("im-module", "") # set up passphrase quality checker self._pwq = pwquality.PWQSettings() self._pwq.read_config() self._pwq.minlen = self.policy.minlen # initialize with the previously set passphrase self.passphrase = self.data.autopart.passphrase if not self.passphrase: self._save_button.set_sensitive(False) self._passphrase_entry.set_text(self.passphrase) self._confirm_entry.set_text(self.passphrase) self._update_passphrase_strength() # Update the check states self._passphrase_match_check.update_check_status() self._strength_check.update_check_status() self._ascii_check.update_check_status()
def validatePassword(pw, user="******", settings=None): """Check the quality of a password. This function does three things: given a password and an optional username, it will tell if this password can be used at all, how strong the password is on a scale of 1-100, and, if the password is unusable, why it is unusuable. This function uses libpwquality to check the password strength. pwquality will raise a PWQError on a weak password, which, honestly, is kind of dumb behavior. A weak password isn't exceptional, it's what we're asking about! Anyway, this function does not raise PWQError. If the password fails the PWQSettings conditions, the first member of the return tuple will be False and the second member of the tuple will be 0. :param pw: the password to check :type pw: string :param user: the username for which the password is being set. If no username is provided, "root" will be used. Use user=None to disable the username check. :type user: string :param settings: an optional PWQSettings object :type settings: pwquality.PWQSettings :returns: A tuple containing (bool(valid), int(score), str(message)) :rtype: tuple """ valid = True message = None strength = 0 if settings is None: # Generate a default PWQSettings once and save it as a member of this function if not hasattr(validatePassword, "pwqsettings"): validatePassword.pwqsettings = pwquality.PWQSettings() validatePassword.pwqsettings.read_config() validatePassword.pwqsettings.minlen = PASSWORD_MIN_LEN settings = validatePassword.pwqsettings for letter in pw: if letter not in PW_ASCII_CHARS: message = _("Requested password contains " "non-ASCII characters, which are " "not allowed.") valid = False break if valid: try: strength = settings.check(pw, None, user) except pwquality.PWQError as e: # Leave valid alone here: the password is weak but can still # be accepted. # PWQError values are built as a tuple of (int, str) message = e[1] return (valid, strength, message)
def get_settings_by_minlen(self, minlen): settings = self._pwq_settings.get(minlen) if settings is None: settings = pwquality.PWQSettings() settings.read_config() settings.minlen = minlen self._pwq_settings[minlen] = settings return settings
def strength(password): score = NotImplemented try: score = pwquality.PWQSettings().check(password) except Exception: score = 0 return score / 20
def check_password(self): if self.password_entry.props.text == "": self.confirm_entry.props.text = "" self.confirm_entry.props.sensitive = False self.password_levelbar.props.value = 0 self.password_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) self.password_error_revealer.set_reveal_child(False) else: self.confirm_entry.props.sensitive = True try: current_password = self.current_password_entry.props.text except: current_password = "" import pwquality password_quality = 0 password_quality_settings = pwquality.PWQSettings() error = None try: password_quality = password_quality_settings.check( self.password_entry.props.text, current_password, None) except pwquality.PWQError as error: error_msg = error if password_quality >= 0: self.password_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, "process-completed-symbolic") self.password_error_revealer.set_reveal_child(False) self.password_levelbar.props.value = password_quality self.is_obscure = True else: self.password_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, "dialog-warning-symbolic") self.password_error_revealer.set_reveal_child(True) self.password_error_label = error_msg.to_string() self.password_levelbar.props.value = 0 self.is_obscure = False return True return False
def __init__(self, password, username=None): self.password = password self.username = username self.pwq_settings = pwquality.PWQSettings() self.pwq_settings.read_config() self.strength = self.MIN_STRENGTH self.pwq_msg = '' try: self.strength = self.pwq_settings.check(self.password, None, self.username) except pwquality.PWQError as (e, msg): self.pwq_msg = msg
def ValidateDictPath(dictpath): if dictpath is None: return dictpath elif dictpath == '-': dictpath = '' pwqs = pwquality.PWQSettings() pwqs.dictpath = dictpath try: pwqs.generate(0) except pwquality.PWQError as e: raise ValueError() return dictpath
def validate_python(self, value, state): # http://xkcd.com/936/ if value.lower() in (u'correct horse battery staple', u'correcthorsebatterystaple', u'tr0ub4dor&3'): raise validators.Invalid(self.message('xkcd', state), value, state) if "pwquality" in modules: try: pw_quality = pwquality.PWQSettings() pw_quality.read_config() pw_quality.check(value, None, None) except pwquality.PWQError as (e, msg): raise validators.Invalid( self.message('pwquality', state) % {'pwq_msg': msg}, value, state)
def root_password(self, password): """Set group job password Set the root password to be used by group jobs. """ if password: try: pwquality.PWQSettings().check(password) except pwquality.PWQError as e: msg = re.sub(r'The password', 'The group root password', e.args[1]) raise ValueError(msg) else: self._root_password = password else: self._root_password = None
def initialize(self): NormalSpoke.initialize(self) if self.data.user.userList: self._user = self.data.user.userList[0] else: self._user = self.data.UserData() self._wheel = self.data.GroupData(name="wheel") self._groupDict = {"wheel": self._wheel} # placeholders for the text boxes self.fullname = self.builder.get_object("t_fullname") self.username = self.builder.get_object("t_username") self.pw = self.builder.get_object("t_password") self.confirm = self.builder.get_object("t_verifypassword") self.admin = self.builder.get_object("c_admin") self.usepassword = self.builder.get_object("c_usepassword") self.b_advanced = self.builder.get_object("b_advanced") self.guesser = {self.username: True} # set up passphrase quality checker self._pwq = pwquality.PWQSettings() self._pwq.read_config() self.pw_bar = self.builder.get_object("password_bar") self.pw_label = self.builder.get_object("password_label") # indicate when the password was set by kickstart self._user.password_kickstarted = self.data.user.seen if self._user.password_kickstarted: self.usepassword.set_active(self._user.password != "") if not self._user.isCrypted: self.pw.set_text(self._user.password) self.confirm.set_text(self._user.password) else: self.usepassword.set_active(True) self.pw.set_placeholder_text( _("The password was set by kickstart.")) self.confirm.set_placeholder_text( _("The password was set by kickstart.")) self._advanced = AdvancedUserDialog(self._user, self._groupDict, self.data) self._advanced.initialize()
def refresh(self): super(PassphraseDialog, self).refresh() # disable input methods for the passphrase Entry widgets and make sure # the focus change mask is enabled self._passphrase_entry = self.builder.get_object("passphrase_entry") self._passphrase_entry.set_property("im-module", "") self._passphrase_entry.set_icon_from_stock( Gtk.EntryIconPosition.SECONDARY, "") self._passphrase_entry.add_events(Gdk.EventMask.FOCUS_CHANGE_MASK) self._confirm_entry = self.builder.get_object("confirm_entry") self._confirm_entry.set_property("im-module", "") self._confirm_entry.add_events(Gdk.EventMask.FOCUS_CHANGE_MASK) self._save_button = self.builder.get_object("passphrase_save_button") self._save_button.set_can_default(True) # add the passphrase strength meter self._strength_bar = Gtk.LevelBar() self._strength_bar.set_mode(Gtk.LevelBarMode.DISCRETE) self._strength_bar.set_min_value(0) self._strength_bar.set_max_value(4) box = self.builder.get_object("strength_box") box.pack_start(self._strength_bar, False, True, 0) box.show_all() self._strength_label = self.builder.get_object("strength_label") # set up passphrase quality checker self._pwq = pwquality.PWQSettings() self._pwq.read_config() # initialize with the previously set passphrase self.passphrase = self.data.autopart.passphrase if not self.passphrase: self._save_button.set_sensitive(False) self._confirm_entry.set_sensitive(False) self._passphrase_entry.set_text(self.passphrase) self._confirm_entry.set_text(self.passphrase) self._update_passphrase_strength()
def _set_root_password(self, password): "Set the password to be used for root on provisioned systems, hashing if necessary" if password: if len(password.split('$')) != 4: try: pwquality.PWQSettings().check(password) except pwquality.PWQError as e: msg = re.sub(r'The password', 'The root password', e.args[1]) raise ValueError(msg) salt = ''.join( random.choice(string.digits + string.ascii_letters) for i in range(8)) self._root_password = crypt.crypt(password, "$1$%s$" % salt) else: self._root_password = password self.rootpw_changed = datetime.utcnow() else: self._root_password = None self.rootpw_changed = None
def _customization(self): valid = False password = None while not valid: password = self.dialog.queryString( name='OVESETUP_CONFIG_ADMIN_SETUP', note=_('Engine admin password: '******'OVESETUP_CONFIG_ADMIN_SETUP', note=_('Confirm engine admin password: '******'Passwords do not match')) else: try: if (_use_pwquality): pwq = pwquality.PWQSettings() pwq.read_config() pwq.check(password, None, None) valid = True except pwquality.PWQError as e: self.logger.warning( _('Password is weak: {error}').format( error=e.args[1], )) valid = dialog.queryBoolean( dialog=self.dialog, name='OVESETUP_CONFIG_WEAK_ENGINE_PASSWORD', note=_('Use weak password? ' '(@VALUES@) [@DEFAULT@]: '), prompt=True, default=False, ) self.environment[oenginecons.ConfigEnv.ADMIN_PASSWORD] = password
def strength(password: str) -> float: """Get strength of a password between 0 and 5. The higher the score is, the more secure the password is. :param str password: password to test :returns: strength of password or None on pwquality error :rtype: float """ # TODO The settings should be set so the strength of the # password is still being computed on certain errors. # For the list of error codes see: # https://github.com/libpwquality/libpwquality/blob/master/src/pwquality.h try: if password: score = pwquality.PWQSettings().check(password) else: score = 0 except pwquality.PWQError: score = 0 return score / 20
def check_password(password): "Checks if a password is valid" # check for length if len(password) < 6: raise ValueError(_('is too short')) # check for entropy pwlen = len(password) ent = entropy(password) idealent = entropy_ideal(pwlen) if (pwlen < 100 and ent / idealent < 0.8) or (pwlen >= 100 and ent < 5.3): raise ValueError(_('isn\'t varied enough')) # check the password strength lc, uc, d, o = 0, 0, 0, 0 for c in password: if c in string.ascii_lowercase: lc += 1 elif c in string.ascii_uppercase: uc += 1 elif c in string.digits: d += 1 else: o += 1 classcount = [lc, uc, d, o] classcount.sort() classcount.reverse() cred = sum([ count * (1 + (weight**2.161 / 10)) for weight, count in zip(range(1, len(classcount) + 1), classcount) ]) if cred < 10: raise ValueError(_('is too weak')) # check if the password is a palindrome for i in range(len(password)): if password[i] != password[-i - 1]: break else: raise ValueError(_('is a palindrome')) # check password with pwquality try: if len(password) < 100: pwquality.PWQSettings().check(password) except (ValueError, pwquality.PWQError) as reason: # modify reason if isinstance(reason, pwquality.PWQError): reason = reason.args[1].replace("The password ", "") reason = str(reason).strip() reason = reason.replace("simplistic/systematic", "systematic") reason = reason.replace(" dictionary", "") if reason[:3] == "it ": reason = reason[3:] if reason[:5] == "it's ": reason = "is " + reason[5:] raise ValueError(reason) except IOError: pass
def validatePassword(pw, user="******", settings=None, minlen=None, empty_ok=False): """Check the quality of a password. This function does three things: given a password and an optional username, it will tell if this password can be used at all, how strong the password is on a scale of 1-100, and, if the password is unusable, why it is unusuable. This function uses libpwquality to check the password strength. pwquality will raise a PWQError on a weak password, which, honestly, is kind of dumb behavior. A weak password isn't exceptional, it's what we're asking about! Anyway, this function does not raise PWQError. If the password fails the PWQSettings conditions, the first member of the return tuple will be False and the second member of the tuple will be 0. :param pw: the password to check :type pw: string :param user: the username for which the password is being set. If no username is provided, "root" will be used. Use user=None to disable the username check. :type user: string :param settings: an optional PWQSettings object :type settings: pwquality.PWQSettings :param int minlen: Minimum acceptable password length. If not passed, use the default length from PASSWORD_MIN_LEN :returns: A tuple containing (bool(valid), int(score), str(message)) :rtype: tuple """ length_ok = False error_message = None pw_quality = 0 # if no passworld length is specified, then require use the Anaconda default minimal # password length (6 characters at the moment) if minlen is None: minlen = PASSWORD_MIN_LEN if settings is None: # Generate a default PWQSettings once and save it as a member of this function if not hasattr(validatePassword, "pwqsettings"): validatePassword.pwqsettings = pwquality.PWQSettings() validatePassword.pwqsettings.read_config() validatePassword.pwqsettings.minlen = minlen settings = validatePassword.pwqsettings try: pw_quality = settings.check(pw, None, user) except pwquality.PWQError as e: # Leave valid alone here: the password is weak but can still # be accepted. # PWQError values are built as a tuple of (int, str) error_message = e.args[1] if empty_ok: # if we are OK with empty passwords, then empty passwords are also fine length wise length_ok = len(pw) >= minlen or not pw else: length_ok = len(pw) >= minlen if not pw: pw_score = 0 status_text = _(PasswordStatus.EMPTY.value) elif not length_ok: pw_score = 0 status_text = _(PasswordStatus.TOO_SHORT.value) elif error_message: pw_score = 1 status_text = _(PasswordStatus.WEAK.value) elif pw_quality < 30: pw_score = 2 status_text = _(PasswordStatus.FAIR.value) elif pw_quality < 70: pw_score = 3 status_text = _(PasswordStatus.GOOD.value) else: pw_score = 4 status_text = _(PasswordStatus.STRONG.value) return pw_score, status_text, pw_quality, error_message
## other materials provided with the distribution. ## ## ## ## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND ANY EXPRESS ## ## OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ## ## THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ## ## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ## ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ## ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ############################################################################################ import pwquality settings = pwquality.PWQSettings() noOfFails = 8 try: try: settings.check("asdf") # Check the score before reading the config file (defaults to /etc/security/pwquality.conf) except pwquality.PWQError as e: if "The password is shorter than 8 characters" in e: noOfFails -= 1 else: print "FAIL: check()" # Read the config file try: settings.read_config() except pwquality.PWQError as e: print "FAIL: read_config()" else: noOfFails -= 1 # check() should refer to the config file with maxlen=11, hence 10 characters try: settings.check("asdf") except pwquality.PWQError as e: