#!/usr/bin/python3 # -*- coding: utf-8 -* # Copyright (C) 2017 Tetras Libre <contact@Tetras-Libre.fr> # Author: Beniamine, David <David.Beniamine@Tetras-Libre.fr> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import os from dateutil.parser import parse from itertools import combinations from zxcvbn import zxcvbn from zxcvbn.matching import add_frequency_lists from translations import tr def add_dictionnaries(): dicts = {} directory = os.path.dirname(os.path.realpath(__file__))+'/../data' for fn in os.listdir(directory): fn = directory+"/"+fn if os.path.isfile(fn): name = os.path.basename(os.path.splitext(fn)[0]) with open(fn) as f: dicts[name] = f.read().splitlines() add_frequency_lists(dicts) # Process user inputs: # Generate all possibile combinations of 2 parts of dates def process_input(inputs): try : dates = [] words = [] for i in inputs: try: date = parse(i) dates += date.strftime("%d-%m-%y-%B-%Y-%A").split('-') except: words.append(i) for n in range(2, 4): for subset in combinations(dates, n): words.append("".join(subset)) return words except: return None def test_pass(password, inputs): # Read input add_dictionnaries() results = zxcvbn(password, process_input(inputs)) lines = [] lines.append("Résultats du test\n") lines.append("Nombre de tentatives : {}".format(results["guesses"])) lines.append("Temps requis pour craquer votre mot de passe") for key, value in results["crack_times_display"].items(): lines.append("\t "+tr(key).capitalize()+" :\t **"+tr(value)+"**") lines.append("\n") lines.append("Methode de hack utilisées") # Print hack methods for seq in results["sequence"]: if seq["pattern"] == "bruteforce": lines.append("\tMot de passe trouvé par force brute") elif seq["pattern"] == "repeat": for match in seq["base_matches"]: line = "\tMot de passe trouvé par répétitions depuis" try: line += "le dictionnaire '{}'".format(tr(match["dictionary_name"])) except: line += "le motif '{}'".format(tr(match["token"])) finally: lines.append(line) elif seq["pattern"] == "date": lines.append("\tMot de passe trouvé par essai de dates") elif seq["pattern"] == "sequence": lines.append("\tMot proche trouvé dans la séquence : '{}'".format(tr(seq["sequence_name"]))) else: lines.append("\tMot proche trouvé dans le dictionnaire : '{}'".format(tr(seq["dictionary_name"]))) lines.append("\n") for key, values in results["feedback"].items(): if values != [] and values != "": lines.append("{} :".format(tr(key).capitalize())) else: continue if not isinstance(values, list): # Simplify things by always using lists values = [values] for val in values: lines.append("\t{}".format(tr(val))) valeur = ["Très faible", "Faible", "Tolérable", "Correct", "Bon"] lines.append("Score Global {}/4 : {}".format(results["score"], valeur[results["score"]])) return lines