Jan,
On 07/26/2012 10:42 AM, Jan Dittberner wrote:
python-cracklib depends on cracklib-runtime and thus should have the necessary
files available. cracklib-runtime only recommends wamerican | wordlist so may
be you don't have a wordlist package installed if your apt configuration is
modified to not install recommends.
Both are installed and available on my machine: cracklib-runtime as well
as wamerican.
I don't know how my cracklib_dict got corrupted and cannot reproduce
that. Fact is, that removing the corrupted files and re-running
`update-cracklib` got me working dicts, again. (I still have a backup of
the corrupted dicts, in case you are interested...)
Note, however, that I'm not complaining about broken dict files, as I'm
unable to exclude a PEBKAC in this case. (Not that I intentionally
fiddled with those, but I just don't have enough clues about what, when,
where, why and for whom it got corrupted).
A bug fix to the upstream code would break the current API and can not be
introduced without changing reverse dependencies. I think this would be much
too late for Wheezy.
Yeah, I've been thinking about that as well.
How about adding (instead of changing) a safe variant of the
FascistCheck function? AFAICT it's the only one used from python. Of
course, nobody should rely on this being available in future versions...
And yes, this only helps python callers. But then again, that's how I
got trapped.
Patch attached. Certainly not a clean solution, yet. But much better
than aborting the python interpreter and thus crashing apps without any
hint on what went wrong.
BTW, with that patch, revelation reports an unknown error and asks to
report it back to its developers. The stack trace:
Traceback (most recent call last):
File /usr/lib/python2.7/dist-packages/revelation/ui.py, line 1057,
in lambda
self.button = Button(_('Generate'), lambda w: self.generate())
File /usr/lib/python2.7/dist-packages/revelation/ui.py, line 1066,
in generate
password =
util.generate_password(self.config.get(passwordgen/length),self.config.get(passwordgen/punctuation))
File /usr/lib/python2.7/dist-packages/revelation/util.py, line 235,
in generate_password
check_password(password)
File /usr/lib/python2.7/dist-packages/revelation/util.py, line 97,
in check_password
cracklib.FascistCheck(password)
RuntimeError: Unable to read cracklib dictionary.
Certainly sounds like they didn't think about cracklib failing in some
way, either...
Regards
Markus Wanner
*goes off filing another bug report*
--- a/lib/fascist.c
+++ b/lib/fascist.c
@@ -879,6 +879,48 @@
return res;
}
+/* This Debian specific method is a work-around for Debian #682735. Please
+ do not rely on it being available in future verisons of cracklib2. */
+int
+__DEBIAN_SPECIFIC__SafeFascistCheck(password, path, errstr)
+const char *password;
+const char *path;
+char *errstr;
+{
+PWDICT *pwp;
+char pwtrunced[STRINGSIZE];
+
+/* If passed null for the path, use a compiled-in default */
+if ( ! path )
+{
+ path = DEFAULT_CRACKLIB_DICT;
+}
+
+/* security problem: assume we may have been given a really long
+ password (buffer attack) and so truncate it to a workable size;
+ try to define workable size as something from which we cannot
+ extend a buffer beyond its limits in the rest of the code */
+
+strncpy(pwtrunced, password, TRUNCSTRINGSIZE);
+pwtrunced[TRUNCSTRINGSIZE - 1] = '\0'; /* enforce */
+
+/* perhaps someone should put something here to check if password
+ is really long and syslog() a message denoting buffer attacks? */
+
+if (!(pwp = PWOpen(path, r)))
+{
+ return 0;
+}
+
+/* sure seems like we should close the database, since we're only likely to check one password */
+errstr = FascistLook(pwp, pwtrunced);
+
+PWClose(pwp);
+pwp = (PWDICT *)0;
+
+return 1;
+}
+
const char *
GetDefaultCracklibDict()
{
--- a/python/_cracklibmodule.c
+++ b/python/_cracklibmodule.c
@@ -42,6 +42,7 @@
#ifdef HAVE_LIBINTL_H
#include libintl.h
#endif
+#include errno.h
#ifdef HAVE_PTHREAD_H
static pthread_mutex_t cracklib_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -74,7 +75,8 @@
{
char *candidate, *dict;
char *defaultdict = NULL;
-const char *result;
+int result;
+char *errmsg;
struct stat st;
char *keywords[] = {pw, dictpath, NULL};
char *dictfile;
@@ -148,7 +150,8 @@
#endif
LOCK();
-result = FascistCheck(candidate, dict ? dict : defaultdict);
+result = __DEBIAN_SPECIFIC__SafeFascistCheck(candidate,
+ dict ? dict : defaultdict, errmsg);
UNLOCK();
if (defaultdict != NULL)
@@ -156,11 +159,26 @@
free(defaultdict);
}
-if (result != NULL)
+if (result)
{
- PyErr_SetString(PyExc_ValueError, result);
-return NULL;
+ if (errmsg != NULL)
+ {
+ PyErr_SetString(PyExc_ValueError, errmsg);
+ return NULL;
+ }
+} else {
+ if (errno