CrackLib Library and Dictionaries
- src - Cracklib distribution itself
- words - scripts and content to build a full size password dictionary
CrackLib Library and Dictionaries
Hello,
There is currently no way to verify the complete integrity of releases. Please consider signing your releases so that package maintainers can verify the sources prior to packaging.
See here for how-to and complete details:
https://wiki.debian.org/Creating%20signed%20GitHub%20releases
Thank you
As highlighted here:
#41
(there's a proposed patch that needs further work, or a full rewrite)
A product that I work with uses cracklib, as is... no customization.
I'm trying to find out what "rules/policies" the library enforces.
Through trial and error, I found out about the following rules. But I'm sure there are other rules. Is there a comprehensive list of all such rules somewhere?
error: Password is based on a dictionary word
meaning: Must not be based on a dictionary word
error: Password is too short
error: Password is WAY too short
meaning: Must be at least 6 characters long.
error: Password does not contain enough DIFFERENT characters
meaning: Must contain at least 5 unique characters (azylmz worked, but azylaz did not)
error: Password is too simplistic/systematic
meaning: Must not contain a sequence/pattern of characters, like 'bcde'.
Note that I was able to create a user with a password that contained only alphabetical characters. So I take it that a password without any numerical or special characters is valid.
(reopened by request from the old hosting site)
To catch bad candidate passwords formulated as described at https://bugzilla.redhat.com/show_bug.cgi?id=909738, I suggest adding purging of digits to the existing rules that purge symbols and punctuation, and perhaps also combinations of these rules.
The autogen.sh
does this:
autopoint -f
cd m4
echo EXTRA_DIST = *.m4 > Makefile.am
cd ..
autoreconf -f -i
autoreconf
will call autopoint
if it detects that gettext is being used. autoconf
will automatically dist any m4 files that are used.
So these changes make the autogen.sh
redundant:
diff --git a/src/Makefile.am b/src/Makefile.am
index 05340bb..b9f8544 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1 +1 @@
-SUBDIRS = m4 lib util po doc python dicts
+SUBDIRS = lib util po doc python dicts
diff --git a/src/configure.ac b/src/configure.ac
index e25f63e..d822902 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -102 +102 @@ AC_CONFIG_FILES([util/Makefile lib/Makefile doc/Makefile python/Makefile Makefil
- po/Makefile.in m4/Makefile dicts/Makefile cracklib.spec])
+ po/Makefile.in dicts/Makefile cracklib.spec])
I've demonstrated this by starting with a clean git checkout, making the changes above, and running autoreconf -sif && ./configure && make && make distcheck
(where distcheck will build a tarball and then verify that will build successfully).
Debian 8.8 x32 - Digitalocean
# uname -a
Linux framework 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2+deb8u2 (2017-06-26) i686 GNU/Linux
# cd ../words
# make all
# install -v -m644 -D ./cracklib-words.gz /usr/share/dict/cracklib-words.gz
# gunzip -v /usr/share/dict/cracklib-words.gz
# ln -v -sf cracklib-words /usr/share/dict/words
# install -v -m755 -d /usr/local/lib/cracklib
# mkdir -p /usr/share/dict/cracklib-words
# mkdir -p /usr/share/dict/cracklib-extra-words
# create-cracklib-dict /usr/share/dict/cracklib-words /usr/share/dict/cracklib-extra-words
Console Error:
rm -f cracklib-words cracklib-words.gz cracklib-words.bz2
rm -f cracklib-words
bzcat -f `find files -type f` | tr A-Z a-z | sort | uniq > cracklib-words
rm -f cracklib-words.gz
gzip -v9 -c cracklib-words > cracklib-words.gz
cracklib-words: 71.1%
rm -f cracklib-words.bz2
bzip2 -v9 -c cracklib-words > cracklib-words.bz2
cracklib-words: 2.756:1, 2.903 bits/byte, 63.71% saved, 19163351 in, 6953913 out.
‘./cracklib-words.gz’ -> ‘/usr/share/dict/cracklib-words.gz’
/usr/share/dict/cracklib-words.gz: 71.1% -- replaced with /usr/share/dict/cracklib-words
‘/usr/share/dict/words’ -> ‘cracklib-words’
...
warning: input out of order: 'ghabcdefghabcdefghabcdefghabcd' should not follow 'habcdefghabcdefghabcdefghabcde' (line 55362)
warning: input out of order: 'fghabcdefghabcdefghabcdefghabc' should not follow 'ghabcdefghabcdefghabcdefghabcd' (line 55363)
warning: input out of order: 'efghabcdefghabcdefghabcdefghab' should not follow 'fghabcdefghabcdefghabcdefghabc' (line 55364)
warning: input out of order: 'fghabcdefghabcdefghabcdefghabc' should not follow 'ghabcdefghabcdefghabcdefghabcd' (line 55366)
warning: input out of order: 'abcdefghi' should not follow 'fghabcdefghabcdefghabcdefghabc' (line 55367)
1911513 1911512
Just after installing cracklib on two different computers I get the following result on each of them when trying to use it for the first time:
echo "123456" | cracklib-check
/nix/store/nck25bk78fhrx70fs8v80hmr0k1z3b39-cracklib-2.9.6/share/cracklib/pw_dict.pwd.gz: No such file or directory
123456: error loading dictionary
Sometime in the past week the cracklib-words-2.9.6.gz has disappeared from your repository. Would you able oto restore? Could be related to previous issue of rearranging the releases section.
A 20-year-old patch adding support for "broken 64-bit" dictionaries is no longer needed and at this point only adds unexercised, untested clutter to the code. To improve the code and to make it simpler to create and test a new patch (see issue #74) I propose that this code be removed.
Back in 2005, a patch was introduced ( commit f247d0c ) which allowed the code to read either dictionary files with the intended 32-bit values for various things in the .pwi
and .hwm
files or with what was called (in the code) "broken 64-bit" dictionary files. That was useful/necessary at the time because prior to 9 Feb 2005 (commit b2a974b) the data type used was typedef unsigned long int int32;
and for some compilers in use at the time, an unsigned long int
was a 64-bit quantity rather than a 32-bit quantity, and the standard allowed (and still allows) this because these are implementation-defined values. The patch allowed the detection and reading of these inadvertent 64-bit dictionaries without user intervention.
While that was a useful fix at the time, twenty years later it is no longer needed and only adds untested clutter to the code. Specifically:
I say "somewhat broken" because we don't really have a way to exercise the 64-bit code in a consistent way, even on the same machine with the same compiler. That is, there is no public recipe for creating such 64-bit dictionaries and so code that might be constructed to do so could do it in at least two different ways. This is because sizeof(struct pi_header64)
on a 64-bit machine using every version of gcc back to version 3.4.6 and every version of clang back to 3.0.0 (and possibly earlier versions and other compilers) will return the value 24 by default, but the value 20 if the -m32
flag is used to target 32-bit machines. Padding and alignment are both implementation-defined details.
(See this example for details.)
When minlen is set to more than 6, let us say 8 The error thrown by cracklib is not correct.
password requisite pam_cracklib.so enforce_for_root retry=3 minlen=8 lcredit=-2 ucredit=-2 dcredit=-1 ocredit=-1 maxsequence=2 reject_username
When I try to change password to KiL@1 password len is 5
The error string thrown is correct
BAD PASSWORD: it is too short
But when password is set to KiLs@13
BAD PASSWORD: it is based on a dictionary word
When Password is set to
KiLs@137
passwd: password updated successfully
The error strings thrown are not consistent would like to see ït is too short" when length is less that 8 when minlen is set to 8
echo "KiL@1" | cracklib-check
KiL@1: it is too short
#echo "KiLs@" | cracklib-check
KiLs@: it is too short
echo "KiLs@1" | cracklib-check
KiLs@1: it is based on a dictionary word
echo "KiLs@137" | cracklib-check
KiLs@137: OK
In the distdifference function it should be less than "<" rather than "<=". Looks like a translation error from the C code. The result is that different strings report a difference of 1 less than it should be e.g.
In [6]: cracklib.distance('xxxxxx', 'kkkkkk')
Out[6]: 5
In [11]: cracklib.distance('a', 'b')
Out[11]: 0
It is not clear whether Python bindings are under LGPL or GPL:
I find references to the LGPL in src/python/_cracklib.c and src/python/cracklib.py, as well as the "classifiers=" in src/python/setup.py.
However, src/python/setup.py's comment header as well as the "license=" parameter state a GPL license.
@jandd, can you please confirm the intended license?
Hello, the Fedora project migrates its translation platform to Weblate [1].
This tool directly interact with your git repository, and requires us to know:
Please note:
[1] https://communityblog.fedoraproject.org/fedora-localization-platform-migrates-to-weblate/
[2] https://docs.weblate.org/en/latest/admin/continuous.html#avoiding-merge-conflicts
[3] https://docs.weblate.org/en/latest/user/checks.html#translation-checks
Hello. This might be my bad eyesight :) but I believe cracklib-update script is missing from the release tarball but is actually called from the Makefile.
https://github.com/cracklib/cracklib/releases/download/v2.9.9/cracklib-2.9.9.tar.bz2
cannot extract file with tar xvjf cracklib-words-2.9.7.bz2
Hi i need to test the cracklib binary files like cracklib-packer, cracklib-unpacker. and scripts cracklib-update, create-cracklib-dict. can any one share the procedure to test those binary?
Hello!
I notice that pam_cracklib don't handle try_first_pass
/use_first_pass
/use_authtok
flags. Because of that, if some higher pam module try to pass some new password, then pam_cracklib accept it, but ask to retype it manually.
To avoid this I use this workaround:
password [success=3 authtok_disable_aging=1 authtok_err=bad default=ignore] pam_unilogon.so
password requisite pam_cracklib.so retry=3 minlen=8 difok=3
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass
# here's the fallback if no module succeeds
password requisite pam_deny.so
My pam module return authtok_disable_aging
to pass new password directly to pam_unix
.
But I believe, that it may be better to add support of this flags to pam_cracklib.so
to allow me do something like that:
password [success=3 authtok_err=bad default=ignore] pam_unilogon.so
password requisite pam_cracklib.so retry=3 minlen=8 difok=3 try_first_pass
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass
# here's the fallback if no module succeeds
password requisite pam_deny.so
Line number 31,566 of the provided word file myspace.txt.bz2 is 6341 characters in length. The cracklib-packer program however only reads up to 1022 characters of a line at a time, any line longer than this is actually treated as multiple separate lines which can then produce "input out of order" warnings if the resultant "new" lines do not happen to appear in sorted order.
Also if any of the input lines are blank, including after cracklib-format has performed some "tr" actions on them a "skipping line: " message is displayed.
When running create-cracklib-dict against the supplied word files the result is the following output:
skipping line: 1
warning: input out of order: 'ghabcdefghabcdefghabcdefghabcd' should not follow 'habcdefghabcdefghabcdefghabcde' (line 55371)
warning: input out of order: 'fghabcdefghabcdefghabcdefghabc' should not follow 'ghabcdefghabcdefghabcdefghabcd' (line 55372)
warning: input out of order: 'efghabcdefghabcdefghabcdefghab' should not follow 'fghabcdefghabcdefghabcdefghabc' (line 55373)
warning: input out of order: 'fghabcdefghabcdefghabcdefghabc' should not follow 'ghabcdefghabcdefghabcdefghabcd' (line 55375)
warning: input out of order: 'abcdefghi' should not follow 'fghabcdefghabcdefghabcdefghabc' (line 55376)
This is the same issue previously reported in #15 3 years ago.
I will be raising a PR to modify the cracklib-format script, used by create-cracklib-dict, to remove these output messages.
A decision still needs to be made whether or not to clean up the myspace.txt.bz2 file to deal with the long line.
https://pypi.org/project/cracklib/ lists 2.9.3 as the most recent version.
I'm trying to install from pip, and 2.9.3 is the latest I can get.
Hello am unable to install cracklib through both pip and pipenv ,i keep getting the error
./_cracklib.c:40:10: fatal error: crack.h: No such file or directory
venv/lib/python3.8/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_py
creating build
creating build/lib.linux-aarch64-cpython-38
copying ./cracklib.py -> build/lib.linux-aarch64-cpython-38
copying ./test_cracklib.py -> build/lib.linux-aarch64-cpython-38
running build_ext
building '_cracklib' extension
creating build/temp.linux-aarch64-cpython-38
aarch64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -I../lib -I/home/samuelishimwe/signnow/venv/include -I/usr/include/python3.8 -c ./_cracklib.c -o build/temp.linux-aarch64-cpython-38/./_cracklib.o
./_cracklib.c:40:10: fatal error: crack.h: No such file or directory
40 | #include <crack.h>
| ^~~~~~~~~
compilation terminated.
error: command '/usr/bin/aarch64-linux-gnu-gcc' failed with exit code 1
[end of output]
The package defaults to finding python2 when both python2 and python3 are on the system. Even when specifying PYTHON=python3.10, configure recognizes it as python-3,1.
I can fix with
autoreconf
PYTHON=3.10 ./configure ...
but that shouldn't be necessary.
Hi, is the name of cracklib thought to be a good one?
looks like all imported tags point to same git commit 8122b0a
Hi,
On Lubuntu 16.04, the grep
in cracklib-format
thinks that the cracklib-words
is a binary file:
$ . src/util/cracklib-format words/cracklib-words.gz
]
]]
binaryfilestandardinputmatches
However, this problem can be avoided if you add a -a
to the grep
in cracklib-format
, to force grep
to treat the input as text:
$ git diff
diff --git a/src/util/cracklib-format b/src/util/cracklib-format
index 1d7be5b..b1de8e8 100644
--- a/src/util/cracklib-format
+++ b/src/util/cracklib-format
@@ -4,7 +4,7 @@
# into cracklib-packer
#
gzip -cdf "$@" |
- grep -v '^\(#\|$\)' |
+ grep -a -v '^\(#\|$\)' |
tr '[A-Z]' '[a-z]' |
tr -cd '\012[a-z][0-9]' |
env LC_ALL=C sort -u
I installed a corpus of 15.998.259 passwords [1] then checked the same [2].
I stopped the process after 282.038 passwords, because of this:
grep ":\ OK" corpus_chk.txt | wc -l
2786
Example of failed password in corpus_chk.txt (originating from the "rockyou" leak):
[1]> create-cracklib-dict corpus.txt
[2]> cat corpus.txt | tr "\n" "\0" | xargs -0 -n1 echo | cracklib-check >corpus_chk.txt
The style of function definitions varies in the source code. Mostly it seems to be K&R, however there are places where ANSI C is used. Unless there is a compelling reason to keep K&R, then I'd say the definitions should be switched over and the standard enforced (e.g. using the -std=c99
compiler option).
Some words checking are skipped, as a result, the result of checking is OK, although they exist in pw_dict.
Reappear question:
[root@study ~]# cat pwdict.txt
Adlfdkfj
Afflaldjf
Testdcljlca
Testcmldsif
Tsfsdf
Tidujoe23
Cllf93
El93lfkdsld
[root@study ~]# create-cracklib-dict pwdict.txt
8 8
[root@study ~]# cracklib-unpacker /usr/share/cracklib/pw_dict > private.txt
[root@study ~]# cat private.txt
adlfdkfj
afflaldjf
cllf93
el93lfkdsld
testcmldsif
testdcljlca
tidujoe23
tsfsdf
[root@study ~]# cat private.txt | while read line;do echo "$line"|cracklib-check;done
adlfdkfj: OK
afflaldjf: it is based on a dictionary word
cllf93: it is based on a dictionary word
el93lfkdsld: it is based on a dictionary word
testcmldsif: it is based on a dictionary word
testdcljlca: it is based on a dictionary word
tidujoe23: it is based on a dictionary word
tsfsdf: it does not contain enough DIFFERENT characters
[root@study ~]#
"adlfdkfj: OK" is wrong.
I think that the question in the functin FindPW() which is in lib/packlib.c.
` middle = lwm + ((hwm - lwm + 1) / 2);
for (;;)
{
int cmp;
#if DEBUG
fprintf(stderr, "lwm = %lu, middle = %lu, hwm = %lu\n", lwm, middle, hwm);
#endif
this = GetPW(pwp, middle);
if ( ! this )
{
#if DEBUG
fprintf(stderr, "getpw returned null, returning null in FindPW\n");
#endif
return(PW_WORDS(pwp));
}
else
{
#if DEBUG
fprintf(stderr, "comparing %s against found %s\n", string, this);
#endif
}
cmp = strcmp(string, this);
if (cmp == 0)
{
return(middle);
}
**if (middle == hwm)**
{
#if DEBUG
fprintf(stderr, "at terminal subdivision, stopping search\n");
#endif
break;
}
if (cmp < 0)
{
hwm = middle;
middle = lwm + ((hwm - lwm ) / 2);
}
else if (cmp > 0)
{
lwm = middle;
middle = lwm + ((hwm - lwm + 1) / 2);
}
}`
The condition “if (middle == hwm)” cause the first word to be skipped.
In https://github.com/cracklib/cracklib/blob/master/src/po/zh_CN.po, the translations are all question marks.
On Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-1091-raspi armv7l) I currently have
cracklib-runtime/now 2.9.2-5build1 armhf [installed,upgradable to: 2.9.6-3.2]
When I run
sudo apt-get install cracklib-runtime
I get the error
Preparing to unpack .../cracklib-runtime_2.9.6-3.2_armhf.deb ...
dpkg: error processing archive /var/cache/apt/archives/cracklib-runtime_2.9.6-3.2_armhf.deb (--unpack):
triggers ci file contains unknown directive 'interest-noaw1it'
Errors were encountered while processing:
/var/cache/apt/archives/cracklib-runtime_2.9.6-3.2_armhf.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
Hi all --
I'm following up on a request to include Hashicorp's packer tool in Fedora, and I notice there is a naming collision on the packer binary that's been tripping up some users for a few years.
The story is that cracklibs distributes a binary file called /usr/sbin/packer
on Fedora and RHEL, and Packer from hashicorp is right now a single statically linked go binary called packer
.
In hopes that we can include Hashicorp's packer in Fedora I am wondering how we can resolve this collision. For example, would it be possible to rename /usr/sbin/packer
to /usr/sbin/packer-cracklibs
?
Hi,
I am trying to update the password with dictionary word as part of the password, but if my password along with the dictionary word has more than 3 characters different cracklib-check accepts it.
Below are few examples captured :
Apple is part of dictionary.
root@localhost:/home/admin# echo Apple@1 | cracklib-check
Apple@1: it is based on a dictionary word
root@localhost:/home/admin# echo Apple@13 | cracklib-check
Apple@13: it is based on a dictionary word
root@localhost:/home/admin# echo Apple@135 | cracklib-check
Apple@135: OK
Apple@135 should also be rejected.
Can you please help me with this. How can this be fixed.
How do I use cracklib-packer to update the weak dictionary of the system instead of overwriting the weak dictionary of the system?
I check my password before setting using by cracklib-check, but it echoes the plaintext password to the terminal.
This may allow others to obtain the password. I think we should avoid displaying plaintext password on the terminal.
For example:
[root@localhost ~]# cracklib-check
TestPwd12
TestPwd12: it is based on a dictionary word
T1e9s$Pwd
T1e9s$Pwd: OK
I have a change like this, please review.
diff --git a/util/check.c b/util/check.c
--- a/util/check.c
+++ b/util/check.c
@@ -8,6 +8,8 @@
#include <limits.h>
#include <string.h>
#include <locale.h>
+#include <termios.h>
+#include <unistd.h>
#define IN_CRACKLIB
#include "config.h"
@@ -20,6 +22,8 @@ main(int argc, char **argv)
char buf[LINE_MAX];
const char *why;
int i;
+ int result = -1;
+ struct termios tios;
setlocale(LC_ALL, "");
@@ -27,6 +31,11 @@ main(int argc, char **argv)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
#endif
+ result = tcgetattr(STDIN_FILENO, &tios);
+ if (!result) {
+ tios.c_lflag &= ~ECHO;
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios);
+ }
while (fgets(buf, sizeof(buf), stdin) != NULL) {
while (((i = strlen(buf)) > 0) && (i > 0)) {
@@ -44,7 +53,7 @@ main(int argc, char **argv)
if ((why != NULL) && (strlen(why) > 0)) {
printf("%s: %s\n", buf, why);
} else {
- printf("%s: OK\n", buf);
+ printf("It is OK\n");
}
}
return 0;
It would be useful if the Python bindings provided an interface to the more general FascistCheckUser() function instead of FascistCheck() (or in addition to it, but it would be trivial to reimplement the Python FascistCheck() and VeryFascistCheck() functions as wrappers to FascistCheckUser() ).
As we all know, today more than ever before, it is crucial to be able to trust
our computing environments. One of the main difficulties that package
maintainers of Linux distributions face, is the difficulty to verify the
authenticity and the integrity of the source code.
The Arch Linux team would appreciate it if you would provide us GPG signatures
in order to verify easily and quickly your source code releases.
Overview of the required tasks:
GPGit is meant to bring GPG to the masses.
It is not only a shell script that automates the process of creating new signed
git releases with GPG but also comes with this step-by-step readme guide for
learning how to use GPG.
This issue will be tracked in the
GPGit Software Sources List.
Additional Information:
Thanks in advance.
I tested the CrackLib library with RockYou password list and i found out that passwords which are not too short and contain a space character are in 90% of cases accepted, the passwords are quite simple,
e.g. 'rock you', 'love you', 'harry potter'.
And passwords that have at least 2 digits as prefix and postfix and are longer than 7 characters are accepted in 70% of cases,
e.g. '123hello123', '123love456', '26dogs26'.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.