Include accountname in totp url
[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 import cracklib
11
12 def cleanup(dir):
13   if not dir.startswith('/tmp/pwcheck-'):
14     raise ValueError, 'cleanup got a weird dir to remove: '+dir
15   for f in 'dict.hwm dict.pwd dict.pwi wordlist wordlist-cleaned'.split(' '):
16     p = dir+'/'+f
17     if os.path.exists(p):
18       os.remove(p)
19   if os.path.exists(dir):
20     os.rmdir(dir)
21
22
23
24 crack_mkdict = None
25 crack_packer = None
26 for b in "/usr/sbin/crack_mkdict /usr/sbin/cracklib-format".split(' '):
27   if os.path.exists(b):
28     crack_mkdict = b
29     break
30 for b in "/usr/sbin/crack_packer /usr/sbin/cracklib-packer".split(' '):
31   if os.path.exists(b):
32     crack_packer = b
33     break
34 if crack_mkdict is None or crack_packer is None:
35   print "Could not find crack formater or packer"
36   sys.exit(1)
37
38
39 newpass = sys.stdin.readline().strip()
40 oldpass = sys.stdin.readline().strip()
41 ldapwords = map( lambda x: x.strip(), sys.stdin.readlines())
42
43 if oldpass == "":
44   oldpass = None
45
46
47 cracklib.min_length = 11
48
49 # check against the default dictionary
50 try:
51   cracklib.VeryFascistCheck(newpass, oldpass, '/var/cache/cracklib/cracklib_dict')
52 except ValueError, e:
53   print e
54   sys.exit(1)
55
56 # and against a dictionary created from the ldap info on this user
57 if len(ldapwords) > 0:
58   # squeeze's cracklib-packer complains about '*' on input - it
59   # says 'skipping line: 1'
60   while '-' in ldapwords:
61     ldapwords.remove('-')
62   while '*' in ldapwords:
63     ldapwords.remove('*')
64
65   tmpdir = tempfile.mkdtemp('', 'pwcheck-')
66   F = open(tmpdir+'/wordlist', "w")
67   for w in ldapwords:
68     F.write(w+"\n");
69   for w1 in ldapwords:
70     for w2 in ldapwords:
71       F.write(w1+w2+"\n");
72       F.write(w1[0]+w2+"\n");
73   F.close()
74
75   r = os.system(crack_mkdict+" "+tmpdir+"/wordlist > "+tmpdir+"/wordlist-cleaned")
76   if r != 0:
77     print "crack_mkdict returned non-zero exit status %d."%(r)
78     cleanup(tmpdir)
79     sys.exit(1)
80   r = os.system(crack_packer+" "+tmpdir+"/dict < "+tmpdir+"/wordlist-cleaned > /dev/null")
81   if r != 0:
82     print "crack_packer returned non-zero exit status %d."%(r)
83     cleanup(tmpdir)
84     sys.exit(1)
85
86   try:
87     cracklib.VeryFascistCheck(newpass, None, tmpdir+"/dict")
88   except ValueError, e:
89     print "ldap data based check: "+str(e)
90     cleanup(tmpdir)
91     sys.exit(1)
92
93   cleanup(tmpdir)
94
95 sys.exit(0)