Skip to content
Snippets Groups Projects
Unverified Commit afd3a3be authored by David Beniamine's avatar David Beniamine
Browse files

Comments + markdown to unify text / html

parent 9cddf434
Branches
No related tags found
No related merge requests found
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
## Todo ## Todo
+ [ ] Traduction + [X] Commentaires
+ [X] Traduction
+ [ ] Nom + [ ] Nom
+ [ ] Readme + [ ] Readme
+ [X] Licence AGPL + [X] Licence AGPL
...@@ -29,6 +30,8 @@ ...@@ -29,6 +30,8 @@
+ [X] Noms + [X] Noms
+ [ ] Packages + [ ] Packages
+ [ ] Installeur + [ ] Installeur
+ [ ] Service systemd
+ [ ] Tests
## Licences ## Licences
......
...@@ -30,6 +30,4 @@ while True: ...@@ -30,6 +30,4 @@ while True:
break break
user_inputs.append(word) user_inputs.append(word)
lines = test_pass(passwd, user_inputs) print(test_pass(passwd, user_inputs))
for line in lines:
print(line)
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
import cgi import cgi
import re import re
from markdown import markdown
from test_pass import test_pass from test_pass import test_pass
form = cgi.FieldStorage() form = cgi.FieldStorage()
...@@ -44,7 +45,9 @@ Tetras Pass ...@@ -44,7 +45,9 @@ Tetras Pass
if form.getvalue("password") is None: if form.getvalue("password") is None:
# Password not defined => show the form # Password not defined => show the form
passwordPrompt = "Veuillez saisir le mot de passe à tester ci dessous :" passwordPrompt = "Veuillez saisir le mot de passe à tester ci dessous :"
inputsPrompt = "Veuillez saisir une liste d'indices : mots ou de dates au format jj/mm/yyyy, un indice par ligne:" inputsPrompt = """Veuillez entrer des indices pour aider à trouver le mot de passe.<br />
Les indicides peuvent être des mots ou des dates au format jj/mm/yyyy.<br/>
Entrez un indice par ligne:"""
sendPrompt = "Lancer le test" sendPrompt = "Lancer le test"
html += """ html += """
...@@ -70,31 +73,14 @@ else: ...@@ -70,31 +73,14 @@ else:
else: else:
inputs = None inputs = None
# Retrieve results # Retrieve results
lines = test_pass(form.getvalue("password"), inputs) html += markdown(test_pass(form.getvalue("password"), inputs))
# Process results for the web
html += "<h2> {} </h2>".format(lines.pop(0))
inlist = False
for line in lines:
line = re.sub('\*\*(.*)\*\*', '<em>\g<1></em>', line)
if line[0] == "\t":
if inlist:
html += "<li>{}</li>".format(line)
else:
inlist = True
html += "<ul><li>{}</li>".format(line)
elif line[0] != "\n":
if inlist:
html += "</ul>"
inlist = False
html += "<h3>{}</h3>".format(line)
html += """ html += """
</div>
</div>
</body> </body>
<foot> <foot>
<div id="foot">
<p> <p>
<a href="https://gitlab.tetras-libre.fr/tetras-libre/tetras-pass">Tetra Pass</a> est Logiciel développé par <a href="https://gitlab.tetras-libre.fr/tetras-libre/tetras-pass">Tetras Pass</a> est Logiciel développé par
<a href="http://tetras-libre.fr">Tetras Libre</a>, <a href="http://tetras-libre.fr">Tetras Libre</a>,
distribué sous Licence <a href="https://www.gnu.org/licenses/agpl.html">AGPL</a> V3.0. distribué sous Licence <a href="https://www.gnu.org/licenses/agpl.html">AGPL</a> V3.0.
</p> </p>
...@@ -107,7 +93,10 @@ Le testeur de mot de passe est basé sur la bibliothèque ...@@ -107,7 +93,10 @@ Le testeur de mot de passe est basé sur la bibliothèque
Les listes de mots et noms français proviennent de <a href="http://www.lexique.org/">lexique.org</a> Les listes de mots et noms français proviennent de <a href="http://www.lexique.org/">lexique.org</a>
et sont distribués sous licence <a href="https://www.gnu.org/licenses/gpl-3.0.txt">GPL</a>. et sont distribués sous licence <a href="https://www.gnu.org/licenses/gpl-3.0.txt">GPL</a>.
</p> </p>
</div>
</foot> </foot>
</div>
</div>
</html> </html>
""" """
......
...@@ -23,6 +23,20 @@ from zxcvbn import zxcvbn ...@@ -23,6 +23,20 @@ from zxcvbn import zxcvbn
from zxcvbn.matching import add_frequency_lists from zxcvbn.matching import add_frequency_lists
from translations import tr from translations import tr
comments = {
'offline_fast_hashing_1e10_per_second':
"L'attaquant.e a accès à une base de donnée d'un site sur lequel vous êtes inscrit et cette base de donnée "
"est mal protégée",
'offline_slow_hashing_1e4_per_second':
"L'attaquant.e a accès à une base de donnée d'un site sur lequel vous êtes inscrit et cette base de donnée est "
"bien protégée",
'online_no_throttling_10_per_second':
"L'attaquant.e essaye de forcer votre mot de passe en ligne, aucune protection anti brute force n'est activée",
'online_throttling_100_per_hour':
"L'attaquant.e essaye de forcer votre mot de passe en ligne, une protection anti brute force n'est activée",
}
def add_dictionnaries(): def add_dictionnaries():
dicts = {} dicts = {}
directory = os.path.dirname(os.path.realpath(__file__))+'/../data' directory = os.path.dirname(os.path.realpath(__file__))+'/../data'
...@@ -55,56 +69,72 @@ def process_input(inputs): ...@@ -55,56 +69,72 @@ def process_input(inputs):
return None return None
# Print results formated in markdown
def test_pass(password, inputs): def test_pass(password, inputs):
# Read input # Read input
add_dictionnaries() add_dictionnaries()
results = zxcvbn(password, process_input(inputs)) results = zxcvbn(password, process_input(inputs))
lines = [] lines = ""
lines.append("Résultats du test\n") lines += "## Résultats du test\n\n"
lines.append("Nombre de tentatives : {}".format(results["guesses"])) lines += "\n\n"
valeur = ["Très faible", "Faible", "Tolérable", "Correct", "Bon"]
lines += "\n### Qualité du mot de passe \n\n"
lines += "+\tNombre de tentatives pour trouver votre mot de passe : **{}**\n".format(results["guesses"])
lines += "+\tScore : **{}/4**\n".format(results["score"])
lines += "+\tJugement : **{}**\n".format(valeur[results["score"]])
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 += "### Temps requis pour craquer votre mot de passe selon le type d'attaque\n"
lines.append("Methode de hack utilisées") lines += "\n\n"
for key, value in sorted(results["crack_times_display"].items()):
lines += "+\t"+tr(key).capitalize()+" :\t **"+tr(value)+"**\n\n"
lines += "\t*Expliquation :* "+comments[key]+", l'attaquant.e vise votre utilisateur en particulier.\n\n"
lines += "\n\n"
lines += "### Methode de hack utilisées\n"
lines += "\n\n"
lines += "Voici la liste des techniques utilisées pour trouver votre mot de passe : \n\n"
prefix = "Votre mot de pass ou une partie de votre mot de passe a été trouvé"
# Print hack methods # Print hack methods
for seq in results["sequence"]: for seq in results["sequence"]:
if seq["pattern"] == "bruteforce": if seq["pattern"] == "bruteforce":
lines.append("\tMot de passe trouvé par force brute") lines += "+\tMot de passe trouvé par force brute\n\n"
lines += "\t{} en testant différentes combinaisons\n\n".format(prefix)
elif seq["pattern"] == "repeat": elif seq["pattern"] == "repeat":
for match in seq["base_matches"]: for match in seq["base_matches"]:
line = "\tMot de passe trouvé par répétitions depuis" line = "+\tMot de passe trouvé par répétitions depuis"
try: try:
line += "le dictionnaire '{}'".format(tr(match["dictionary_name"])) line += "le dictionnaire '{}'".format(tr(match["dictionary_name"]))
except: except:
line += "le motif '{}'".format(tr(match["token"])) line += "le motif '{}'".format(tr(match["token"]))
finally: finally:
lines.append(line) lines += line+"\n"
lines += "\t{} en répétant un motif ou mot connu\n\n".format(prefix)
elif seq["pattern"] == "date": elif seq["pattern"] == "date":
lines.append("\tMot de passe trouvé par essai de dates") lines += "+\tMot de passe trouvé par essai de dates\n\n"
lines += "\t{} est une date, récente facile à deviner\n\n".format(prefix)
elif seq["pattern"] == "sequence": elif seq["pattern"] == "sequence":
lines.append("\tMot proche trouvé dans la séquence : '{}'".format(tr(seq["sequence_name"]))) lines += "+\tMot proche trouvé dans la séquence : '{}'\n\n".format(tr(seq["sequence_name"]))
lines += "\t{} est une séquence de caractères facile à deviner\n\n".format(prefix)
else: else:
lines.append("\tMot proche trouvé dans le dictionnaire : '{}'".format(tr(seq["dictionary_name"]))) lines += "+\tMot proche trouvé dans le dictionnaire : '{}'\n\n".format(tr(seq["dictionary_name"]))
lines += "\t{} est dans un dictionnaire de mots connus\n\n".format(prefix)
lines.append("\n")
lines += "\n### Problemes et conseils\n"
for key, values in results["feedback"].items(): for key, values in results["feedback"].items():
if values != [] and values != "": if values != [] and values != "":
lines.append("{} :".format(tr(key).capitalize())) lines += "\n\n"
lines += "#### {}\n\n".format(tr(key).capitalize())
else: else:
continue continue
if not isinstance(values, list): if not isinstance(values, list):
# Simplify things by always using lists # Simplify things by always using lists
values = [values] values = [values]
for val in values: for val in values:
lines.append("\t{}".format(tr(val))) lines += "+\t{}\n".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 return lines
...@@ -27,7 +27,7 @@ translations = { ...@@ -27,7 +27,7 @@ translations = {
'online_throttling_100_per_hour': 'Essai en ligne avec protection anti brute force', 'online_throttling_100_per_hour': 'Essai en ligne avec protection anti brute force',
'passwords': 'mots de passes', 'passwords': 'mots de passes',
'surnames': 'nom de famille', 'surnames': 'nom de famille',
'user_input': "indices données par l'attaquant.e", 'user_inputs': "indices données par l'attaquant.e",
'suggestions': 'conseils', 'suggestions': 'conseils',
'warning': 'problèmes', 'warning': 'problèmes',
'less than a second': "moins d'une seconde", 'less than a second': "moins d'une seconde",
...@@ -77,15 +77,14 @@ substitutions = { ...@@ -77,15 +77,14 @@ substitutions = {
'All-uppercase is almost as easy to guess as all-lowercase': 'All-uppercase is almost as easy to guess as all-lowercase':
'Les mots en majuscules sont aussi simple à deviner que ceux en minuscules', 'Les mots en majuscules sont aussi simple à deviner que ceux en minuscules',
"Reversed words aren't much harder to guess": 'Les mots inversés ne sont pas beaucoup plus dur à deviner', "Reversed words aren't much harder to guess": 'Les mots inversés ne sont pas beaucoup plus dur à deviner',
} }
def tr(text): def tr(text):
try: try:
return translations[text] text = translations[text]
except: except:
# Todo use regex
for pattern, sub in substitutions.items(): for pattern, sub in substitutions.items():
text = re.sub(pattern, sub, text) text = re.sub(pattern, sub, text)
finally:
return text return text
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment