From 0daba3ec4ce446b8bea91b785fbf0f9d80c06cdc Mon Sep 17 00:00:00 2001 From: Olof-Joachim Frahm Date: Wed, 21 Jan 2015 23:54:07 +0000 Subject: [PATCH] Better GUI, password reading, translation. Kinda too big, this commit. Also has encoding problems. --- crypto-install | 122 +++++++++++++++++++++++-------- locale/crypto-install.pot | 108 ++++++++++++++++----------- locale/de/LC_MESSAGES/crypto-install.po | 112 +++++++++++++++++----------- 3 files changed, 226 insertions(+), 116 deletions(-) diff --git a/crypto-install b/crypto-install index 6fb3a7c..f0a881c 100755 --- a/crypto-install +++ b/crypto-install @@ -11,6 +11,7 @@ if sys.version_info[0] == 2: from tkMessageBox import * from Tix import * from ScrolledText import * + from ttk import * from Queue import * @@ -25,6 +26,7 @@ elif sys.version_info[0] > 2: from tkinter.messagebox import * from tkinter.tix import * from tkinter.scrolledtext import * + from tkinter.ttk import * from queue import * @@ -170,8 +172,10 @@ def openssh_exists (arguments): return os.path.exists (openssh_config) and os.path.exists (openssh_key) -# TODO: verify phrase at least once -# TODO: use better labels +def quoted (string): + return string.replace ("+", "++").replace (" ", "+") + + def input_passphrase (arguments): batch_passphrase = ldedented (""" RESET @@ -180,6 +184,8 @@ def input_passphrase (arguments): """).format (subprocess.check_output ("tty").strip (), os.getenv ("TERM")) + expected_oks = 3 + batch_env = dict (os.environ) if arguments.gui: batch_passphrase += ldedented (""" @@ -187,27 +193,65 @@ def input_passphrase (arguments): OPTION display={} """).format (os.getenv ("XAUTHORITY"), os.getenv ("DISPLAY")) + expected_oks += 2 else: del batch_env["DISPLAY"] - batch_passphrase += \ - "GET_PASSPHRASE --data --check --qualitybar X X Passphrase X\n" - passphrase_process = subprocess.Popen (["gpg-agent", "--server"], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, env = batch_env) - (stdout, stderr) = passphrase_process.communicate (batch_passphrase.encode ("UTF-8")) - if passphrase_process.returncode != 0: - raise Exception ("Couldn't read passphrase.") + try: + line = passphrase_process.stdout.readline ().decode ("UTF-8") + if line != "OK Pleased to meet you\n": + raise Exception ("Couldn't read expected OK.") - for line in stdout.splitlines (): - if line.decode ("UTF-8").startswith ("D "): - return line[2:] + passphrase_process.stdin.write (batch_passphrase.encode ("UTF-8")) - return "" + for i in range (expected_oks): + line = passphrase_process.stdout.readline ().decode ("UTF-8") + if line != "OK\n": + raise Exception ("Couldn't read expected OK.") + + error, prompt, description = "", _ ("Passphrase:"), "" + + while True: + batch_passphrase = \ + "GET_PASSPHRASE --data --repeat=1 --qualitybar X {} {} {}\n" \ + .format ((error and quoted (error)) or "X", + (prompt and quoted (prompt)) or "X", + (description and quoted (description)) or "X") + + passphrase_process.stdin.write (batch_passphrase.encode ("UTF-8")) + + line = passphrase_process.stdout.readline ().decode ("UTF-8") + + if line == "OK\n": + error = _ ("Empty passphrase") + continue + + if line.startswith ("D "): + passphrase = line[2:-1] + + if len (passphrase) < 8: + error = _ ("Passphrase too short") + description = _ ("Passphrase has to have at least 8 characters.") + continue + + return passphrase + + if line.startswith ("ERR 83886179"): + raise Exception ("Operation cancelled.") + + raise Exception ("Unexpected response.") + finally: + passphrase_process.stdin.close () + passphrase_process.stdout.close () + passphrase_process.stderr.close () + + passphrase_process.wait () def redirect_to_stdout (process): @@ -349,22 +393,6 @@ def _state (value): return NORMAL if value else DISABLED -def _valid (value): - return "black" if value else "red" - - -def setitem (object, name, value): - return object.__setitem__ (name, value) - - -def setitems (name, value, objects): - return map (lambda object: setitem (object, name, value), objects) - - -def _fg (value, *objects): - setitems ("fg", value, objects) - - # http://www.blog.pythonlibrary.org/2014/07/14/tkinter-redirecting-stdout-stderr/ # http://www.virtualroadside.com/blog/index.php/2012/11/10/glib-idle_add-for-tkinter-in-python/ class RedirectText (object): @@ -400,21 +428,37 @@ class CryptoInstallProgress (Toplevel): self._quit = Button (self, text = _ ("Quit"), - command = self.quit) + command = self.maybe_quit) self.balloon.bind_widget (self._quit, msg = _ ("Quit the program immediately")) self._quit.pack () + def update_widgets (self): + if self.parent.state () == "normal": + self._quit["text"] = _ ("Close") + self.balloon.bind_widget (self._quit, + msg = _ ("Close this window")) + + def maybe_quit (self): + (self.quit if self.parent.state () != "normal" else self.destroy) () + class CryptoInstall (Tk): def __init__ (self, arguments): Tk.__init__ (self) + self.style = Style () + self.style.theme_use ("clam") + self.style.configure ("Invalid.TLabel", foreground = "red") + self.style.configure ("Invalid.TEntry", foreground = "red") + self.arguments = arguments self.resizable (width = False, height = False) self.title (_ ("Crypto Install Wizard")) + self.progress = None + self.create_widgets () def create_widgets (self): @@ -580,7 +624,10 @@ class CryptoInstall (Tk): def update_field (self, name): field = self.fields[name] - _fg (_valid (field[1] (field[0].get ())), field[2], field[3]) + valid = field[1] (field[0].get ()) + + field[2]["style"] = "" if valid else "Invalid.TEntry" + field[3]["style"] = "" if valid else "Invalid.TLabel" def update_widgets (self, *args): self._generate["state"] = _state (self.valid_state ()) @@ -633,7 +680,16 @@ class CryptoInstall (Tk): openssh_setup (self.arguments, comment) # TODO: put update into queue self.update_widgets () + except Exception as exception: + self.deiconify () + + sys.stdout.write (exception) + sys.stdout.write ("\n") + + raise finally: + # TODO: put update into queue + self.progress.update_widgets () sys.stdout = stdout def _on_idle (): @@ -645,7 +701,11 @@ class CryptoInstall (Tk): pass def generate (self): - self.progress = CryptoInstallProgress (self) + self.withdraw () + + if not self.progress or self.progress.winfo_exists () == 0: + self.progress = CryptoInstallProgress (self) + self.progress.text.delete ("0.0", "end") self.bind ("<>", self._on_idle) diff --git a/locale/crypto-install.pot b/locale/crypto-install.pot index 5773c40..43bf3dd 100644 --- a/locale/crypto-install.pot +++ b/locale/crypto-install.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-01-18 22:56+0000\n" +"POT-Creation-Date: 2015-01-21 23:50+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,138 +17,162 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: crypto-install:76 +#: crypto-install:75 msgid "Display version." msgstr "" -#: crypto-install:81 +#: crypto-install:80 msgid "Disable GUI, use text interface." msgstr "" -#: crypto-install:83 +#: crypto-install:82 msgid "GnuPG" msgstr "" -#: crypto-install:84 +#: crypto-install:83 msgid "Options related to the GnuPG setup." msgstr "" -#: crypto-install:89 +#: crypto-install:88 msgid "Disable GnuPG setup." msgstr "" -#: crypto-install:94 crypto-install:108 +#: crypto-install:93 crypto-install:107 msgid "PATH" msgstr "" -#: crypto-install:95 +#: crypto-install:94 msgid "Default directory for GnuPG files." msgstr "" -#: crypto-install:97 +#: crypto-install:96 msgid "OpenSSH" msgstr "" -#: crypto-install:98 +#: crypto-install:97 msgid "Options related to the OpenSSH setup." msgstr "" -#: crypto-install:103 +#: crypto-install:102 msgid "Disable OpenSSH setup." msgstr "" -#: crypto-install:109 +#: crypto-install:108 msgid "Default directory for OpenSSH files." msgstr "" -#: crypto-install:234 -msgid "GnuPG secret keyring already exists at '{}'." +#: crypto-install:218 +msgid "Passphrase:" +msgstr "" + +#: crypto-install:232 +msgid "Empty passphrase" msgstr "" #: crypto-install:239 +msgid "Passphrase too short" +msgstr "" + +#: crypto-install:240 +msgid "Passphrase has to have at least 8 characters." +msgstr "" + +#: crypto-install:275 +msgid "GnuPG secret keyring already exists at '{}'." +msgstr "" + +#: crypto-install:280 msgid "" "\n" " No default GnuPG key available. Please enter your information to\n" " create a new key." msgstr "" -#: crypto-install:243 +#: crypto-install:284 msgid "What is your name (e.g. 'John Doe')? " msgstr "" -#: crypto-install:246 +#: crypto-install:287 msgid "" "\n" " What is your email address (e.g. 'test@example.com')? " msgstr "" -#: crypto-install:250 +#: crypto-install:291 msgid "" "\n" " What is your comment phrase, if any (e.g. 'key for 2014')? " msgstr "" -#: crypto-install:255 +#: crypto-install:296 msgid "Creating GnuPG directory at '{}'." msgstr "" -#: crypto-install:299 +#: crypto-install:340 msgid "Creating OpenSSH directory at '{}'." msgstr "" -#: crypto-install:302 +#: crypto-install:343 msgid "Creating OpenSSH configuration at '{}'." msgstr "" -#: crypto-install:313 crypto-install:319 +#: crypto-install:354 crypto-install:360 msgid "OpenSSH key already exists at '{}'." msgstr "" -#: crypto-install:322 +#: crypto-install:363 msgid "No OpenSSH key available. Generating new key." msgstr "" -#: crypto-install:326 +#: crypto-install:367 msgid "" "\n" " What is your comment phrase (e.g. 'user@mycomputer')? " msgstr "" -#: crypto-install:405 crypto-install:551 +#: crypto-install:430 crypto-install:592 msgid "Quit" msgstr "" -#: crypto-install:408 crypto-install:554 +#: crypto-install:433 crypto-install:595 msgid "Quit the program immediately" msgstr "" -#: crypto-install:419 +#: crypto-install:438 +msgid "Close" +msgstr "" + +#: crypto-install:440 +msgid "Close this window" +msgstr "" + +#: crypto-install:458 msgid "Crypto Install Wizard" msgstr "" -#: crypto-install:431 +#: crypto-install:472 msgid "" "\n" " Username on the local machine (e.g. 'user')\n" " " msgstr "" -#: crypto-install:434 +#: crypto-install:475 msgid "Username" msgstr "" -#: crypto-install:448 +#: crypto-install:489 msgid "" "\n" " Host name of the local machine (e.g. 'mycomputer')\n" " " msgstr "" -#: crypto-install:451 +#: crypto-install:492 msgid "Host Name" msgstr "" -#: crypto-install:465 +#: crypto-install:506 msgid "" "\n" " Full name as it should appear in the key description (e.g. 'John " @@ -156,56 +180,56 @@ msgid "" " " msgstr "" -#: crypto-install:468 +#: crypto-install:509 msgid "Full Name" msgstr "" -#: crypto-install:482 +#: crypto-install:523 msgid "" "\n" " Email address associated with the name (e.g. '')\n" " " msgstr "" -#: crypto-install:485 +#: crypto-install:526 msgid "Email address" msgstr "" -#: crypto-install:499 +#: crypto-install:540 msgid "" "\n" " Comment phrase for the GnuPG key, if any (e.g. 'key for 2014')\n" " " msgstr "" -#: crypto-install:502 +#: crypto-install:543 msgid "Comment phrase" msgstr "" -#: crypto-install:520 +#: crypto-install:561 msgid "Generate GnuPG key" msgstr "" -#: crypto-install:531 +#: crypto-install:572 msgid "Generate OpenSSH key" msgstr "" -#: crypto-install:544 +#: crypto-install:585 msgid "Generate Keys" msgstr "" -#: crypto-install:548 +#: crypto-install:589 msgid "Generate the keys as configured above" msgstr "" -#: crypto-install:608 +#: crypto-install:652 msgid "" "\n" " Generate a GnuPG key for '{}' and configure a default setup for it\n" " " msgstr "" -#: crypto-install:615 +#: crypto-install:659 msgid "" "\n" " Generate an OpenSSH key for '{}' and configure a default setup for " diff --git a/locale/de/LC_MESSAGES/crypto-install.po b/locale/de/LC_MESSAGES/crypto-install.po index 423422a..962c77c 100644 --- a/locale/de/LC_MESSAGES/crypto-install.po +++ b/locale/de/LC_MESSAGES/crypto-install.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-01-18 22:56+0000\n" +"POT-Creation-Date: 2015-01-21 23:50+0000\n" "PO-Revision-Date: 2015-01-17 12:29+0000\n" "Last-Translator: Olof-Joachim Frahm \n" "Language-Team: German \n" @@ -18,67 +18,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: crypto-install:76 +#: crypto-install:75 msgid "Display version." msgstr "Version anzeigen." -#: crypto-install:81 +#: crypto-install:80 msgid "Disable GUI, use text interface." msgstr "Schalte GUI ab, benutze das Textinterface." -#: crypto-install:83 +#: crypto-install:82 msgid "GnuPG" msgstr "GnuPG" -#: crypto-install:84 +#: crypto-install:83 msgid "Options related to the GnuPG setup." msgstr "Optionen für das GnuPG-Setup." -#: crypto-install:89 -#, fuzzy +#: crypto-install:88 msgid "Disable GnuPG setup." msgstr "GnuPG-Setup deaktivieren." -#: crypto-install:94 crypto-install:108 +#: crypto-install:93 crypto-install:107 msgid "PATH" msgstr "PFAD" -#: crypto-install:95 +#: crypto-install:94 msgid "Default directory for GnuPG files." msgstr "Standardverzeichnis für GnuPG-Dateien." -#: crypto-install:97 +#: crypto-install:96 msgid "OpenSSH" msgstr "OpenSSH" -#: crypto-install:98 +#: crypto-install:97 msgid "Options related to the OpenSSH setup." msgstr "Optionen für das OpenSSH-Setup." -#: crypto-install:103 +#: crypto-install:102 msgid "Disable OpenSSH setup." msgstr "OpenSSH-Setup deaktivieren." -#: crypto-install:109 +#: crypto-install:108 msgid "Default directory for OpenSSH files." msgstr "Standardverzeichnis für OpenSSH-Dateien." -#: crypto-install:234 +#: crypto-install:218 +msgid "Passphrase:" +msgstr "Passwort:" + +#: crypto-install:232 +msgid "Empty passphrase" +msgstr "Leeres Passwort" + +#: crypto-install:239 +msgid "Passphrase too short" +msgstr "Passwort zu kurz" + +#: crypto-install:240 +msgid "Passphrase has to have at least 8 characters." +msgstr "Passwort muß mindestens 8 Zeichen lang sein." + +#: crypto-install:275 msgid "GnuPG secret keyring already exists at '{}'." msgstr "Geheimer GnuPG-Schlüssel existiert bereits unter '{}'." -#: crypto-install:239 +#: crypto-install:280 msgid "" "\n" " No default GnuPG key available. Please enter your information to\n" " create a new key." msgstr "" +"\n" +" Kein Standard GnuPG-Schlüssel vorhanden. Bitte gib Deine Informationen um\n" +" einen neuen Schlüssel zu erstellen." -#: crypto-install:243 +#: crypto-install:284 msgid "What is your name (e.g. 'John Doe')? " msgstr "Wie heißt Du (z.B. 'Max Mustermann')? " -#: crypto-install:246 +#: crypto-install:287 msgid "" "\n" " What is your email address (e.g. 'test@example.com')? " @@ -86,7 +104,7 @@ msgstr "" "\n" " Was ist Deine Email-Adresse? (z.B. 'test@example.com')? " -#: crypto-install:250 +#: crypto-install:291 msgid "" "\n" " What is your comment phrase, if any (e.g. 'key for 2014')? " @@ -94,27 +112,27 @@ msgstr "" "\n" " Was ist Dein Kommentar, falls gewünscht (z.B. 'Schlüssel für 2014')? " -#: crypto-install:255 +#: crypto-install:296 msgid "Creating GnuPG directory at '{}'." msgstr "Erstelle GnuPG-Verzeichnis unter '{}'." -#: crypto-install:299 +#: crypto-install:340 msgid "Creating OpenSSH directory at '{}'." msgstr "Erstelle OpenSSH-Verzeichnis unter '{}'." -#: crypto-install:302 +#: crypto-install:343 msgid "Creating OpenSSH configuration at '{}'." msgstr "Erstelle OpenSSH-Konfiguration unter '{}'." -#: crypto-install:313 crypto-install:319 +#: crypto-install:354 crypto-install:360 msgid "OpenSSH key already exists at '{}'." msgstr "OpenSSH-Schlüssel existiert bereits unter '{}'." -#: crypto-install:322 +#: crypto-install:363 msgid "No OpenSSH key available. Generating new key." msgstr "Kein OpenSSH-Schlüssel verfügbar. Erstelle neuen Schlüssel." -#: crypto-install:326 +#: crypto-install:367 msgid "" "\n" " What is your comment phrase (e.g. 'user@mycomputer')? " @@ -122,19 +140,27 @@ msgstr "" "\n" " Was ist Dein Kommentar (z.B. 'benutzer@meincomputer')? " -#: crypto-install:405 crypto-install:551 +#: crypto-install:430 crypto-install:592 msgid "Quit" msgstr "Beenden" -#: crypto-install:408 crypto-install:554 +#: crypto-install:433 crypto-install:595 msgid "Quit the program immediately" msgstr "Programm sofort beenden" -#: crypto-install:419 +#: crypto-install:438 +msgid "Close" +msgstr "Schließen" + +#: crypto-install:440 +msgid "Close this window" +msgstr "Schließe dieses Fenster" + +#: crypto-install:458 msgid "Crypto Install Wizard" msgstr "Crypto Installationsassistent" -#: crypto-install:431 +#: crypto-install:472 msgid "" "\n" " Username on the local machine (e.g. 'user')\n" @@ -144,11 +170,11 @@ msgstr "" " Benutzername am lokalen Rechner (z.B. 'benutzer')\n" " " -#: crypto-install:434 +#: crypto-install:475 msgid "Username" msgstr "Benutzername" -#: crypto-install:448 +#: crypto-install:489 msgid "" "\n" " Host name of the local machine (e.g. 'mycomputer')\n" @@ -158,11 +184,11 @@ msgstr "" " Hostname des lokalen Rechners (z.B. 'meincomputer')\n" " " -#: crypto-install:451 +#: crypto-install:492 msgid "Host Name" msgstr "Hostname" -#: crypto-install:465 +#: crypto-install:506 msgid "" "\n" " Full name as it should appear in the key description (e.g. 'John " @@ -174,11 +200,11 @@ msgstr "" "B. 'Max Mustermann')\n" " " -#: crypto-install:468 +#: crypto-install:509 msgid "Full Name" msgstr "Voller Name" -#: crypto-install:482 +#: crypto-install:523 msgid "" "\n" " Email address associated with the name (e.g. '')\n" @@ -188,11 +214,11 @@ msgstr "" " Dem Namen zugeordnete Emailadresse (z.B. '')\n" " " -#: crypto-install:485 +#: crypto-install:526 msgid "Email address" msgstr "Emailadresse" -#: crypto-install:499 +#: crypto-install:540 msgid "" "\n" " Comment phrase for the GnuPG key, if any (e.g. 'key for 2014')\n" @@ -203,27 +229,27 @@ msgstr "" "für 2014')\n" " " -#: crypto-install:502 +#: crypto-install:543 msgid "Comment phrase" msgstr "Kommentar" -#: crypto-install:520 +#: crypto-install:561 msgid "Generate GnuPG key" msgstr "GnuPG-Schlüssel erstellen" -#: crypto-install:531 +#: crypto-install:572 msgid "Generate OpenSSH key" msgstr "OpenSSH-Schlüssel erstellen" -#: crypto-install:544 +#: crypto-install:585 msgid "Generate Keys" msgstr "Schlüssel erstellen" -#: crypto-install:548 +#: crypto-install:589 msgid "Generate the keys as configured above" msgstr "Schlüssel wie oben konfiguriert erstellen" -#: crypto-install:608 +#: crypto-install:652 msgid "" "\n" " Generate a GnuPG key for '{}' and configure a default setup for it\n" @@ -234,7 +260,7 @@ msgstr "" "Standardsetup dafür\n" " " -#: crypto-install:615 +#: crypto-install:659 msgid "" "\n" " Generate an OpenSSH key for '{}' and configure a default setup for " -- 1.7.10.4