From 1b045dd14e590093800469e2e96e6a71f6b92955 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss <erdnaxe@crans.org> Date: Sun, 12 Apr 2020 20:34:20 +0200 Subject: [PATCH] Remove unicode 'u' --- client.py | 160 ++++++++++++++++++++++++++---------------------------- 1 file changed, 78 insertions(+), 82 deletions(-) diff --git a/client.py b/client.py index 354d530..4680fe6 100755 --- a/client.py +++ b/client.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python2 -# -*- encoding: utf-8 -*- +#!/usr/bin/env python3 """Gestion centralisée des mots de passe avec chiffrement GPG @@ -8,8 +7,6 @@ Authors : Daniel Stan <daniel.stan@crans.org> Vincent Le Gallic <legallic@crans.org> """ -from __future__ import print_function - # Import builtins import sys import subprocess @@ -25,7 +22,6 @@ import time import datetime import copy import logging -from binascii import hexlify from configparser import ConfigParser # Import a SSH client @@ -70,16 +66,16 @@ GPG_ARGS = { #: Mapping (lettre de trustlevel) -> (signification, faut-il faire confiance à la clé) GPG_TRUSTLEVELS = { - u"-" : (u"inconnue (pas de valeur assignée)", False), - u"o" : (u"inconnue (nouvelle clé)", False), - u"i" : (u"invalide (self-signature manquante ?)", False), - u"n" : (u"nulle (il ne faut pas faire confiance à cette clé)", False), - u"m" : (u"marginale (pas assez de lien de confiance vers cette clé)", False), - u"f" : (u"entière (clé dans le réseau de confiance)", True), - u"u" : (u"ultime (c'est probablement ta clé)", True), - u"r" : (u"révoquée", False), - u"e" : (u"expirée", False), - u"q" : (u"non définie", False), + "-" : ("inconnue (pas de valeur assignée)", False), + "o" : ("inconnue (nouvelle clé)", False), + "i" : ("invalide (self-signature manquante ?)", False), + "n" : ("nulle (il ne faut pas faire confiance à cette clé)", False), + "m" : ("marginale (pas assez de lien de confiance vers cette clé)", False), + "f" : ("entière (clé dans le réseau de confiance)", True), + "u" : ("ultime (c'est probablement ta clé)", True), + "r" : ("révoquée", False), + "e" : ("expirée", False), + "q" : ("non définie", False), } def gpg(options, command, args=None): @@ -167,7 +163,7 @@ GPG_PARSERS = { def parse_keys(gpgout, debug=False): """Parse l'output d'un listing de clés gpg.""" ring = {} - init_value = u"initialize" # Valeur utilisée pour dire "cet objet n'a pas encore été rencontré pendant le parsing" + init_value = "initialize" # Valeur utilisée pour dire "cet objet n'a pas encore été rencontré pendant le parsing" current_pub = init_value current_sub = init_value for line in iter(gpgout.readline, ''): @@ -191,35 +187,35 @@ def parse_keys(gpgout, debug=False): except: log.error("*** FAILED *** Line: %s", line) raise - if field == u"pub": + if field == "pub": # Nouvelle clé # On sauvegarde d'abord le dernier sub (si il y en a un) dans son pub parent if current_sub != init_value: current_pub["subkeys"].append(current_sub) # Ensuite on sauve le pub précédent (si il y en a un) dans le ring if current_pub != init_value: - ring[current_pub[u"fpr"]] = current_pub + ring[current_pub["fpr"]] = current_pub # On place le nouveau comme pub courant current_pub = content # Par défaut, il n'a ni subkeys, ni uids - current_pub[u"subkeys"] = [] - current_pub[u"uids"] = [] + current_pub["subkeys"] = [] + current_pub["uids"] = [] # On oublié l'éventuel dernier sub rencontré current_sub = init_value - elif field == u"fpr": + elif field == "fpr": if current_sub != init_value: # On a lu un sub depuis le dernier pub, donc le fingerprint est celui du dernier sub rencontré - current_sub[u"fpr"] = content[u"fpr"] + current_sub["fpr"] = content["fpr"] else: # Alors c'est le fingerprint du pub - current_pub[u"fpr"] = content[u"fpr"] - elif field == u"uid": - current_pub[u"uids"].append(content) - elif field == u"sub": + current_pub["fpr"] = content["fpr"] + elif field == "uid": + current_pub["uids"].append(content) + elif field == "sub": # Nouvelle sous-clé # D'abord on sauvegarde la précédente (si il y en a une) dans son pub parent if current_sub != init_value: - current_pub[u"subkeys"].append(current_sub) + current_pub["subkeys"].append(current_sub) # On place la nouvelle comme sub courant current_sub = content log.debug("current_pub : %r" % current_pub) @@ -230,7 +226,7 @@ def parse_keys(gpgout, debug=False): if current_sub != init_value: current_pub["subkeys"].append(current_sub) if current_pub != init_value: - ring[current_pub[u"fpr"]] = current_pub + ring[current_pub["fpr"]] = current_pub return ring class simple_memoize(object): @@ -361,7 +357,7 @@ def get_my_roles(options): """Retourne la liste des rôles de l'utilisateur, et également la liste des rôles dont il possède le role-w.""" allroles = all_roles(options) distant_username = allroles.pop("whoami") - my_roles = [r for (r, users) in allroles.iteritems() if distant_username in users] + my_roles = [r for (r, users) in allroles.items() if distant_username in users] my_roles_w = [r[:-2] for r in my_roles if r.endswith("-w")] return (my_roles, my_roles_w) @@ -389,21 +385,21 @@ def _check_encryptable(key): Puis qu'on peut chiffrer avec, ou qu'au moins une de ses subkeys est de chiffrement (capability e) et est de confiance et n'est pas expirée""" # Il faut que la clé soit dans le réseau de confiance… - meaning, trustvalue = GPG_TRUSTLEVELS[key[u"trustletter"]] + meaning, trustvalue = GPG_TRUSTLEVELS[key["trustletter"]] if not trustvalue: - return u"La confiance en la clé est : %s" % (meaning,) + return "La confiance en la clé est : %s" % (meaning,) # …et qu'on puisse chiffrer avec… - if u"e" in key[u"capabilities"]: + if "e" in key["capabilities"]: # …soit directement… - return u"" + return "" # …soit avec une de ses subkeys - esubkeys = [sub for sub in key[u"subkeys"] if u"e" in sub[u"capabilities"]] + esubkeys = [sub for sub in key["subkeys"] if "e" in sub["capabilities"]] if len(esubkeys) == 0: - return u"La clé principale de permet pas de chiffrer et auncune sous-clé de chiffrement." - if any([GPG_TRUSTLEVELS[sub[u"trustletter"]][1] for sub in esubkeys]): - return u"" + return "La clé principale de permet pas de chiffrer et auncune sous-clé de chiffrement." + if any([GPG_TRUSTLEVELS[sub["trustletter"]][1] for sub in esubkeys]): + return "" else: - return u"Aucune sous clé de chiffrement n'est de confiance et non expirée." + return "Aucune sous clé de chiffrement n'est de confiance et non expirée." def check_keys(options, recipients=None, quiet=False): """Vérifie les clés, c'est-à -dire, si le mail est présent dans les identités du fingerprint, @@ -427,15 +423,15 @@ def check_keys(options, recipients=None, quiet=False): _, gpgout = gpg(options, 'list-keys') localring = parse_keys(gpgout) for (recipient, (mail, fpr)) in keys.iteritems(): - failed = u"" + failed = "" if not fpr is None: if speak: - print((u"Checking %s… " % (mail)).encode("utf-8"), end="") + print(("Checking %s… " % (mail)).encode("utf-8"), end="") key = localring.get(fpr, None) # On vérifie qu'on possède la clé… if not key is None: # …qu'elle correspond au mail… - if any([u"<%s>" % (mail,) in u["uid"] for u in key["uids"]]): + if any(["<%s>" % (mail,) in u["uid"] for u in key["uids"]]): if speak: print("M ", end="") # … et qu'on peut raisonnablement chiffrer pour lui @@ -443,16 +439,16 @@ def check_keys(options, recipients=None, quiet=False): if not failed and speak: print("C ", end="") else: - failed = u"!! Le fingerprint et le mail ne correspondent pas !" + failed = "!! Le fingerprint et le mail ne correspondent pas !" else: - failed = u"Pas (ou trop) de clé avec ce fingerprint." + failed = "Pas (ou trop) de clé avec ce fingerprint." if speak: print("") if failed: log.warn("--> Fail on %s:%s\n--> %s" % (mail, fpr, failed)) if not recipients is None: # On cherche à savoir si on droppe ce recipient - message = u"Abandonner le chiffrement pour cette clé ? (Si vous la conservez, il est posible que gpg crashe)" + message = "Abandonner le chiffrement pour cette clé ? (Si vous la conservez, il est posible que gpg crashe)" if confirm(options, message, ('drop', fpr, mail)): drop = True # si on a répondu oui à "abandonner ?", on droppe elif options.drop_invalid and options.force: @@ -475,7 +471,7 @@ def get_recipients_of_roles(options, roles): recipients = set() allroles = all_roles(options) for role in roles: - if role == u"whoami": + if role == "whoami": continue for recipient in allroles[role]: recipients.add(recipient) @@ -484,7 +480,7 @@ def get_recipients_of_roles(options, roles): def get_dest_of_roles(options, roles): """Renvoie la liste des "username : mail (fingerprint)" """ allkeys = all_keys(options) - return [u"%s : %s (%s)" % (rec, allkeys[rec][0], allkeys[rec][1]) + return ["%s : %s (%s)" % (rec, allkeys[rec][0], allkeys[rec][1]) for rec in get_recipients_of_roles(options, roles) if allkeys[rec][1]] def encrypt(options, roles, contents): @@ -505,7 +501,7 @@ def encrypt(options, roles, contents): stdin.close() out = stdout.read().decode("utf-8") if out == '': - return [False, u"Échec de chiffrement"] + return [False, "Échec de chiffrement"] else: return [True, out] @@ -540,7 +536,7 @@ def need_filename(f): NEED_FILENAME.append(f) return f -def editor(texte, annotations=u""): +def editor(texte, annotations=""): """ Lance $EDITOR sur texte. Renvoie le nouveau texte si des modifications ont été apportées, ou None """ @@ -570,40 +566,40 @@ def show_files(options): """Affiche la liste des fichiers disponibles sur le serveur distant""" my_roles, _ = get_my_roles(options) files = all_files(options) - keys = files.keys() + keys = list(files.keys()) keys.sort() - print(u"Liste des fichiers disponibles :".encode("utf-8")) + print("Liste des fichiers disponibles :".encode("utf-8")) for fname in keys: froles = files[fname] access = set(my_roles).intersection(froles) != set([]) - print((u" %s %s (%s)" % ((access and '+' or '-'), fname, ", ".join(froles))).encode("utf-8")) - print((u"""--Mes roles: %s""" % (", ".join(my_roles),)).encode("utf-8")) + print((" %s %s (%s)" % ((access and '+' or '-'), fname, ", ".join(froles))).encode("utf-8")) + print(("""--Mes roles: %s""" % (", ".join(my_roles),)).encode("utf-8")) def restore_files(options): """Restore les fichiers corrompues sur le serveur distant""" - print(u"Fichier corrompus :".encode("utf-8")) + print("Fichier corrompus :".encode("utf-8")) files = restore_all_files(options) keys = files.keys() keys.sort() for fname in keys: - print((u" %s (%s)" % ( fname, files[fname])).encode("utf-8")) + print((" %s (%s)" % ( fname, files[fname])).encode("utf-8")) def show_roles(options): """Affiche la liste des roles existants""" - print(u"Liste des roles disponibles".encode("utf-8")) + print("Liste des roles disponibles".encode("utf-8")) allroles = all_roles(options) for (role, usernames) in allroles.iteritems(): - if role == u"whoami": + if role == "whoami": continue if not role.endswith('-w'): - print((u" * %s : %s" % (role, ", ".join(usernames))).encode("utf-8")) + print((" * %s : %s" % (role, ", ".join(usernames))).encode("utf-8")) def show_servers(options): """Affiche la liste des serveurs disponibles""" - print(u"Liste des serveurs disponibles".encode("utf-8")) + print("Liste des serveurs disponibles".encode("utf-8")) for server in config.keys(): - print((u" * " + server).encode("utf-8")) + print((" * " + server).encode("utf-8")) def saveclipboard(restore=False, old_clipboard=None): """Enregistre le contenu du presse-papier. Le rétablit si ``restore=True``""" @@ -615,7 +611,7 @@ def saveclipboard(restore=False, old_clipboard=None): if not restore: old_clipboard = proc.stdout.read() else: - raw_input(u"Appuyez sur Entrée pour récupérer le contenu précédent du presse papier.".encode("utf-8")) + raw_input("Appuyez sur Entrée pour récupérer le contenu précédent du presse papier.".encode("utf-8")) proc.stdin.write(old_clipboard) proc.stdin.close() proc.stdout.close() @@ -657,7 +653,7 @@ def show_file(options): # Est-ce que le mot de passe a été caché ? (si non, on utilisera less) is_hidden = is_key # Texte avec mdp caché - filtered = u"" + filtered = "" # Ancien contenu du press papier old_clipboard = None @@ -673,12 +669,12 @@ def show_file(options): # On met le mdp dans le clipboard en mémorisant son ancien contenu old_clipboard = clipboard(catchPass.group(1)) # Et donc on override l'affichage - line = u"[Le mot de passe a été mis dans le presse papier]" + line = "[Le mot de passe a été mis dans le presse papier]" filtered += line + '\n' if is_key: - filtered = u"La clé a été mise dans l'agent ssh" - shown = u"Fichier %s:\n\n%s-----\nVisible par: %s\n" % (fname, filtered, ','.join(passfile['roles'])) + filtered = "La clé a été mise dans l'agent ssh" + shown = "Fichier %s:\n\n%s-----\nVisible par: %s\n" % (fname, filtered, ','.join(passfile['roles'])) if is_key: with tempfile.NamedTemporaryFile(suffix='') as key_file: @@ -717,22 +713,22 @@ def edit_file(options): fname = options.fname gotit, value = get_file(options, fname) nfile = False - annotations = u"" + annotations = "" my_roles, _ = get_my_roles(options) new_roles = options.roles # Cas du nouveau fichier - if not gotit and not u"pas les droits" in value: + if not gotit and not "pas les droits" in value: nfile = True if not options.quiet: - print(u"Fichier introuvable".encode("utf-8")) - if not confirm(options, u"Créer fichier ?"): + print("Fichier introuvable".encode("utf-8")) + if not confirm(options, "Créer fichier ?"): return - annotations += u"""Ceci est un fichier initial contenant un mot de passe + annotations += """Ceci est un fichier initial contenant un mot de passe aléatoire, pensez à rajouter une ligne "login: ${login}" Enregistrez le fichier vide pour annuler.\n""" - texte = u"pass: %s\n" % gen_password() + texte = "pass: %s\n" % gen_password() if new_roles is None: new_roles = parse_roles(options, cast=True) @@ -763,13 +759,13 @@ Enregistrez le fichier vide pour annuler.\n""" # On peut vouloir chiffrer un fichier sans avoir la possibilité de le lire # dans le futur, mais dans ce cas on préfère demander confirmation if not any(r + '-w' in my_roles for r in new_roles): - message = u"""Vous vous apprêtez à perdre vos droits en écriture""" + \ + message = """Vous vous apprêtez à perdre vos droits en écriture""" + \ """(ROLES ne contient rien parmi : %s) sur ce fichier, continuer ?""" message = message % (", ".join(r[:-2] for r in my_roles if '-w' in r),) if not confirm(options, message): return - annotations += u"""Ce fichier sera chiffré pour les rôles suivants :\n%s\n + annotations += """Ce fichier sera chiffré pour les rôles suivants :\n%s\n C'est-à -dire pour les utilisateurs suivants :\n%s""" % ( ', '.join(new_roles), '\n'.join(' %s' % rec for rec in get_dest_of_roles(options, new_roles)) @@ -780,9 +776,9 @@ C'est-à -dire pour les utilisateurs suivants :\n%s""" % ( if ((not nfile and ntexte in [u'', texte] # pas nouveau, vidé ou pas modifié and set(new_roles) == set(passfile['roles'])) # et on n'a même pas touché à ses rôles, or (nfile and ntexte == u'')): # ou alors on a créé un fichier vide. - message = u"Pas de modification à enregistrer.\n" - message += u"Si ce n'est pas un nouveau fichier, il a été vidé ou n'a pas été modifié (même pas ses rôles).\n" - message += u"Si c'est un nouveau fichier, vous avez tenté de le créer vide." + message = "Pas de modification à enregistrer.\n" + message += "Si ce n'est pas un nouveau fichier, il a été vidé ou n'a pas été modifié (même pas ses rôles).\n" + message += "Si c'est un nouveau fichier, vous avez tenté de le créer vide." if not options.quiet: print(message.encode("utf-8")) else: @@ -826,8 +822,8 @@ def remove_file(options): def my_check_keys(options): """Vérifie les clés et affiche un message en fonction du résultat""" - print(u"Vérification que les clés sont valides (uid correspondant au login) et de confiance.") - print((check_keys(options) and u"Base de clés ok" or u"Erreurs dans la base").encode("utf-8")) + print("Vérification que les clés sont valides (uid correspondant au login) et de confiance.") + print((check_keys(options) and "Base de clés ok" or "Erreurs dans la base").encode("utf-8")) def my_update_keys(options): """Met à jour les clés existantes et affiche le résultat""" @@ -870,8 +866,8 @@ def recrypt_files(options, strict=False): # On informe l'utilisateur et on demande confirmation avant de rechiffrer # Si il a précisé --force, on ne lui demandera rien. filenames = ", ".join(askfiles) - message = u"Vous vous apprêtez à rechiffrer les fichiers suivants :\n%s" % filenames - if not confirm(options, message + u"\nConfirmer"): + message = "Vous vous apprêtez à rechiffrer les fichiers suivants :\n%s" % filenames + if not confirm(options, message + "\nConfirmer"): exit(2) # On rechiffre to_put = [{'filename' : f['filename'], @@ -880,15 +876,15 @@ def recrypt_files(options, strict=False): for [success, f] in files] if to_put: if not options.quiet: - print((u"Rechiffrement de %s" % (", ".join([f['filename'] for f in to_put]))).encode("utf-8")) + print(("Rechiffrement de %s" % (", ".join([f['filename'] for f in to_put]))).encode("utf-8")) results = put_files(options, to_put) # On affiche les messages de retour if not options.quiet: for i in range(len(results)): - print(u"%s : %s" % (to_put[i]['filename'], results[i][1])) + print("%s : %s" % (to_put[i]['filename'], results[i][1])) else: if not options.quiet: - print(u"Aucun fichier n'a besoin d'être rechiffré".encode("utf-8")) + print("Aucun fichier n'a besoin d'être rechiffré".encode("utf-8")) def parse_roles(options, cast=False): """Interprête la liste de rôles fournie par l'utilisateur. -- GitLab