{"id":20135969,"url":"https://github.com/openwall/passwdqc","last_synced_at":"2025-07-05T17:33:27.103Z","repository":{"id":44432747,"uuid":"328803255","full_name":"openwall/passwdqc","owner":"openwall","description":"Password/passphrase strength checking and policy enforcement","archived":false,"fork":false,"pushed_at":"2024-11-05T15:03:58.000Z","size":760,"stargazers_count":41,"open_issues_count":6,"forks_count":17,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-12-07T08:41:39.953Z","etag":null,"topics":["complexity","enforcement","libpasswdqc","pam","passphrase","passwdqc","password","policy","pwqcheck","pwqfilter","pwqgen","strength"],"latest_commit_sha":null,"homepage":"https://www.openwall.com/passwdqc/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openwall.png","metadata":{"files":{"readme":"README","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-11T22:06:20.000Z","updated_at":"2024-12-02T15:29:52.000Z","dependencies_parsed_at":"2024-05-06T07:47:17.614Z","dependency_job_id":"19b291b3-2f57-493c-ab11-bc8388d867a7","html_url":"https://github.com/openwall/passwdqc","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwall%2Fpasswdqc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwall%2Fpasswdqc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwall%2Fpasswdqc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openwall%2Fpasswdqc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openwall","download_url":"https://codeload.github.com/openwall/passwdqc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230438191,"owners_count":18225871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["complexity","enforcement","libpasswdqc","pam","passphrase","passwdqc","password","policy","pwqcheck","pwqfilter","pwqgen","strength"],"created_at":"2024-11-13T21:17:11.974Z","updated_at":"2024-12-19T13:08:59.866Z","avatar_url":"https://github.com/openwall.png","language":"C","readme":"pam_passwdqc is a simple password strength checking module for\nPAM-aware password changing programs, such as passwd(1).  In addition\nto checking regular passwords, it offers support for passphrases and\ncan provide randomly generated ones.  All features are optional and\ncan be (re-)configured without rebuilding.\n\nThis module should be stacked before your usual password changing\nmodule (such as pam_unix or pam_pwdb) in the password management group\n(the \"password\" lines in /etc/pam.d/passwd or /etc/pam.conf).  The\npassword changing module should then be told to use the provided new\nauthentication token (new password) rather than request it from the\nuser.  There's usually the \"use_authtok\" option to do that.  If your\npassword changing module lacks the \"use_authtok\" option or its prompts\nare inconsistent with pam_passwdqc's, you may tell pam_passwdqc to ask\nfor the old password as well, with \"ask_oldauthtok\".  In that case the\noption to use with the password changing module is \"use_first_pass\".\n\nThere are a number of supported options, which can be used to modify the\nbehavior of pam_passwdqc (defaults are given in square brackets):\n\n\tconfig=FILE\t\t\t[]\n\nLoad the specified configuration FILE, which must be in the\npasswdqc.conf format (described in the passwdqc.conf(5) manual page).\nThis file may define any options described in here, including load of\nyet another configuration file, but loops are not allowed.\n\n\tmin=N0,N1,N2,N3,N4\t\t[min=disabled,24,11,8,7]\n\nThe minimum allowed password lengths for different kinds of passwords\nand passphrases.  The keyword \"disabled\" can be used to disallow\npasswords of a given kind regardless of their length.  Each subsequent\nnumber is required to be no larger than the preceding one.\n\nN0 is used for passwords consisting of characters from one character\nclass only.  The character classes are: digits, lower-case letters,\nupper-case letters, and other characters.  There is also a special\nclass for non-ASCII characters, which could not be classified, but are\nassumed to be non-digits.\n\nN1 is used for passwords consisting of characters from two character\nclasses that do not meet the requirements for a passphrase.\n\nN2 is used for passphrases.  Note that besides meeting this length\nrequirement, a passphrase must also consist of a sufficient number of\nwords (see the \"passphrase\" option below).\n\nN3 and N4 are used for passwords consisting of characters from three\nand four character classes, respectively.\n\nWhen calculating the number of character classes, upper-case letters\nused as the first character and digits used as the last character of a\npassword are not counted.\n\nIn addition to being sufficiently long, passwords are required to\ncontain enough different characters for the character classes and\nthe minimum length they have been checked against.\n\n\tmax=N\t\t\t\t[max=72]\n\nThe maximum allowed password length.  This can be used to prevent\nusers from setting passwords that may be too long for some system\nservices.\n\nThe value 8 is treated specially: with max=8, passwords longer than 8\ncharacters will not be rejected, but will be truncated to 8 characters\nfor the strength checks and the user will be warned.  This is to be\nused with the traditional DES-based password hashes, which truncate\nthe password at 8 characters.\n\nIt is important that you do set max=8 if you are using the traditional\nhashes, or some weak passwords will pass the checks.\n\n\tpassphrase=N\t\t\t[passphrase=3]\n\nThe number of words required for a passphrase, or 0 to disable the\nsupport for user-chosen passphrases.\n\n\tmatch=N\t\t\t\t[match=4]\n\nThe length of common substring required to conclude that a password is\nat least partially based on information found in a character string,\nor 0 to disable the substring search.  Note that the password will not\nbe rejected once a weak substring is found; it will instead be\nsubjected to the usual strength requirements with the weak substring\npartially discounted.\n\nThe substring search is case-insensitive and is able to detect and\nremove a common substring spelled backwards.\n\n\tsimilar=permit|deny\t\t[similar=deny]\n\nWhether a new password is allowed to be similar to the old one.  The\npasswords are considered to be similar when there is a sufficiently\nlong common substring and the new password with the substring partially\ndiscounted would be weak.\n\n\twordlist=FILE\t\t\t[]\n\nDeny passwords that are based on lines of a tiny external text file,\nwhich can reasonably be e.g. a list of a few thousand common passwords.\nCommon dictionary words may also reasonably be included, especially in a\nlocal language other than English, or longer yet common English words.\n(passwdqc includes a list of a few thousand common English words of\nlengths from 3 to 6 built in.  Any word list possibly specified with\nthis option is used in addition to the built-in word list.)\n\nSubstring matching and discounting will be used if the \"match\" setting\nabove is non-zero.  Please note that this is very inefficient, and isn't\nto be used with large wordlists.\n\n\tdenylist=FILE\t\t\t[]\n\nDeny passwords or passphrases directly appearing in a tiny external text\nfile.  That file can reasonably be e.g. a list of common passwords if\nonly a relaxed policy is desired and stricter checks are thus disabled\n(using their separate options).  Such policy would only be somewhat\neffective against online/remote attacks, but not against offline attacks\non hashed passwords.\n\n\tfilter=FILE\t\t\t[]\n\nDeny passwords or passphrases directly appearing in a maybe huge binary\nfilter file created with pwqfilter.  This is very efficient, needing at\nmost two random disk reads per query.  A filter created from millions of\nleaked passwords can reasonably be used on top of passwdqc's other\nchecks to further reduce the number of passing yet weak passwords\nwithout causing unreasonable inconvenience (as e.g. higher minimum\nlengths and character set requirements could).\n\n\trandom=N[,only]\t\t\t[random=47]\n\nThe size of randomly-generated passphrases in bits (24 to 136), or 0 to\ndisable this feature.  Any passphrase that contains the offered\nrandomly-generated string will be allowed regardless of other possible\nrestrictions.\n\nThe \"only\" modifier can be used to disallow user-chosen passwords.\n\n\tenforce=none|users|everyone\t[enforce=everyone]\n\nThe module can be configured to warn of weak passwords only, but not\nactually enforce strong passwords.  The \"users\" setting is like\n\"everyone\" for all PAM services except \"chpasswd\" and \"passwd\".\nFor these two PAM services \"users\" will enforce strong passwords\nfor invocations by non-root users only.\n\n\tnon-unix\t\t\t[]\n\nNormally, the module uses getpwnam(3) to obtain the user's personal\nlogin information and use that during the password strength checks.\nThis behavior can be disabled with the \"non-unix\" option.\n\n\tretry=N\t\t\t\t[retry=3]\n\nThe number of times the module will ask for a new password if the user\nfails to provide a sufficiently strong password and enter it twice the\nfirst time.\n\n\task_oldauthtok[=update]\t\t[]\n\nAsk for the old password as well.  Normally, pam_passwdqc leaves this\ntask for subsequent modules.  With no argument, the \"ask_oldauthtok\"\noption will cause pam_passwdqc to ask for the old password during the\npreliminary check phase.  With \"ask_oldauthtok=update\", pam_passwdqc\nwill do that during the update phase.\n\n\tcheck_oldauthtok\t\t[]\n\nThis tells pam_passwdqc to validate the old password before giving a\nnew password prompt.  Normally, this task is left for subsequent\nmodules.\n\nThe primary use for this option is when \"ask_oldauthtok=update\" is\nalso specified, in which case no other module gets a chance to ask\nfor and validate the password.  Of course, this will only work with\nUnix passwords.\n\n\tuse_first_pass\t\t\t[]\n\tuse_authtok\t\t\t[]\n\nUse the new password obtained by modules stacked before pam_passwdqc.\nThis disables user interaction within pam_passwdqc.  With this module,\nthe only difference between \"use_first_pass\" and \"use_authtok\" is that\nthe former is incompatible with \"ask_oldauthtok\".\n\n\tnoaudit\t\t\t\t[]\n\nIf audit is enabled at build time, the PAM module logs audit events once\nuser tries to change their credentials.  This option disables that audit\nlogging.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenwall%2Fpasswdqc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenwall%2Fpasswdqc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenwall%2Fpasswdqc/lists"}