# python-crack - Python bindings for cracklib # Copyright (C) 2003 Domenico Andreoli # # This file is part of python-crack. # # python-crack is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # python-crack is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Prua; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import string from _crack import * ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ascii_lowercase = "abcdefghijklmnopqrstuvwxyz" diff_ok = 5 min_length = 9 dig_credit = 1 up_credit = 1 low_credit = 1 oth_credit = 1 def palindrome(s): for i in range(len(s)): if s[i] != s[-i - 1]: return 0 return 1 # Calculate how different two strings are in terms of the number of # character removals, additions, and changes needed to go from one to # the other def distdifferent(old, new, i, j): if i == 0 or len(old) <= i: c = 0 else: c = old[i - 1] if j == 0 or len(new) <= i: d = 0 else: d = new[j - 1] return c != d def distcalculate(distances, old, new, i, j): tmp = 0 if distances[i][j] != -1: return distances[i][j] tmp = distcalculate(distances, old, new, i - 1, j - 1) tmp = min(tmp, distcalculate(distances, old, new, i , j - 1)) tmp = min(tmp, distcalculate(distances, old, new, i - 1, j )) tmp = tmp + distdifferent(old, new, i, j) distances[i][j] = tmp return tmp def distance(old, new): m = len(old) n = len(new) distances = [ [] for i in range(m + 1) ] for i in range(m + 1): distances[i] = [ -1 for j in range(n + 1) ] for i in range(m + 1): distances[i][0] = i for j in range(n + 1): distances[0][j] = j distances[0][0] = 0 r = distcalculate(distances, old, new, m, n) for i in range(len(distances)): for j in range(len(distances[i])): distances[i][j] = 0 return r def similar(old, new): if distance(old, new) >= diff_ok: return 0 if len(new) >= (len(old) * 2): return 0 # passwords are too similar return 1 def simple(new): digits = 0 uppers = 0 lowers = 0 others = 0 for c in new: if c in string.digits: digits = digits + 1 elif c in ascii_uppercase: uppers = uppers + 1 elif c in ascii_lowercase: lowers = lowers + 1 else: others = others + 1 # The scam was this - a password of only one character type # must be 8 letters long. Two types, 7, and so on. # This is now changed, the base size and the credits or defaults # see the docs on the module for info on these parameters, the # defaults cause the effect to be the same as before the change if dig_credit >= 0 and digits > dig_credit: digits = dig_credit if up_credit >= 0 and uppers > up_credit: uppers = up_credit if low_credit >= 0 and lowers > low_credit: lowers = low_credit if oth_credit >= 0 and others > oth_credit: others = oth_credit size = min_length if dig_credit >= 0: size = size - digits elif digits < (dig_credit * -1): return 1 if up_credit >= 0: size = size - uppers elif uppers < (up_credit * -1): return 1 if low_credit >= 0: size = size - lowers elif lowers < (low_credit * -1): return 1 if oth_credit >= 0: size = size - others elif others < (oth_credit * -1): return 1 if len(new) < size: return 1 return 0 def VeryFascistCheck(new, old = None, dictpath = None): if dictpath == None: dictpath = default_dictpath if old != None: if new == old: raise ValueError, "is the same as the old one" oldmono = old.lower() newmono = new.lower() wrapped = old + old if newmono == oldmono: raise ValueError, "case changes only" if wrapped.find(new) != -1: raise ValueError, "is rotated" if similar(oldmono, newmono): raise ValueError, "is too similar to the old one" FascistCheck(new, dictpath) if palindrome(new): raise ValueError, "is a palindrome" if simple(new): raise ValueError, "is too simple" return new