Make it work on lenny too
[mirror/userdir-ldap-cgi.git] / password-qualify-check
1 #!/usr/bin/python
2
3 # check password quality using cracklib given a new password, optionally the
4 # old password, and a list of ldap/gecos words via stdin, each on a line by
5 # itself (send an empty line if you want to skip the old password check)
6
7 # Copyright (c) 2008 Peter Palfrader
8
9 import sys, tempfile, os
10 try:
11   import crack as cracklib
12 except ImportError:
13   import cracklib
14
15 def cleanup(dir):
16   if not dir.startswith('/tmp/pwcheck-'):
17     raise ValueError, 'cleanup got a weird dir to remove: '+dir
18   for f in 'dict.hwm dict.pwd dict.pwi wordlist wordlist-cleaned'.split(' '):
19     p = dir+'/'+f
20     if os.path.exists(p):
21       os.remove(p)
22   if os.path.exists(dir):
23     os.rmdir(dir)
24
25
26
27 crack_mkdict = None
28 crack_packer = None
29 for b in "/usr/sbin/crack_mkdict /usr/sbin/cracklib-format".split(' '):
30   if os.path.exists(b):
31     crack_mkdict = b
32     break
33 for b in "/usr/sbin/crack_packer /usr/sbin/cracklib-packer".split(' '):
34   if os.path.exists(b):
35     crack_packer = b
36     break
37 if crack_mkdict is None or crack_packer is None:
38   print "Could not find crack formater or packer"
39   sys.exit(1)
40
41
42 newpass = sys.stdin.readline().strip()
43 oldpass = sys.stdin.readline().strip()
44 ldapwords = map( lambda x: x.strip(), sys.stdin.readlines())
45
46 if oldpass == "":
47   oldpass = None
48
49
50 cracklib.min_length = 11
51
52 # check against the default dictionary
53 try:
54   cracklib.VeryFascistCheck(newpass, oldpass, '/var/cache/cracklib/cracklib_dict')
55 except ValueError, e:
56   print e
57   sys.exit(1)
58
59 # and against a dictionary created from the ldap info on this user
60 if len(ldapwords) > 0:
61   tmpdir = tempfile.mkdtemp('', 'pwcheck-')
62   F = open(tmpdir+'/wordlist', "w")
63   for w in ldapwords:
64     F.write(w+"\n");
65   for w1 in ldapwords:
66     for w2 in ldapwords:
67       F.write(w1+w2+"\n");
68       F.write(w1[0]+w2+"\n");
69   F.close()
70
71   r = os.system(crack_mkdict+" "+tmpdir+"/wordlist > "+tmpdir+"/wordlist-cleaned")
72   if r != 0:
73     print "crack_mkdict returned non-zero exit status %d."%(r)
74     cleanup(tmpdir)
75     sys.exit(1)
76   r = os.system(crack_packer+" "+tmpdir+"/dict < "+tmpdir+"/wordlist-cleaned > /dev/null")
77   if r != 0:
78     print "crack_packer returned non-zero exit status %d."%(r)
79     cleanup(tmpdir)
80     sys.exit(1)
81
82   try:
83     cracklib.VeryFascistCheck(newpass, None, tmpdir+"/dict")
84   except ValueError, e:
85     print "ldap data based check: "+str(e)
86     cleanup(tmpdir)
87     sys.exit(1)
88
89   cleanup(tmpdir)
90
91 sys.exit(0)