[master 1/1] Do not allow passphrases to be typed with non-ASCII keymaps (#681250)
dashea
installerbot-noreply at redhat.com
Mon Aug 31 20:57:22 UTC 2015
From: David Shea <dshea at redhat.com>
Keymaps are complicated, and it's impossible to know whether a
particular passphrase will be typable at boot time, but we can be pretty
sure that anything from a non-ASCII keymap will not be typable. If the
user is attempting to use such a keymap in the passphrase dialog,
disable input and display an error message.
---
pyanaconda/ui/gui/spokes/lib/passphrase.py | 42 ++++++++++++++++++++++++++++++
pyanaconda/ui/gui/xkl_wrapper.py | 4 +++
2 files changed, 46 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/lib/passphrase.py b/pyanaconda/ui/gui/spokes/lib/passphrase.py
index 580a1d3..10e9bfd 100644
--- a/pyanaconda/ui/gui/spokes/lib/passphrase.py
+++ b/pyanaconda/ui/gui/spokes/lib/passphrase.py
@@ -25,13 +25,16 @@
from gi.repository import Gtk
import pwquality
+import langtable
from pyanaconda.ui.helpers import InputCheck
from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.helpers import GUIInputCheckHandler
+from pyanaconda.ui.helpers import InputCheckHandler
from pyanaconda.constants import PW_ASCII_CHARS
from pyanaconda.i18n import _, N_
from pyanaconda.ui.gui.utils import really_hide, really_show
+from pyanaconda.ui.gui.xkl_wrapper import XklWrapper
__all__ = ["PassphraseDialog"]
@@ -73,6 +76,18 @@ def __init__(self, data):
self._pwq_error = None
self.passphrase = ""
+ # due to the contraints of the keymap at boot time, do not allow input
+ # from non-ASCII keymaps. This check depends on the current active keymap
+ # and not any particular input, but add it as an input check so that the error
+ # message is displayed through the same mechanism. Use add_check from InputCheckHandler
+ # so that no real input object is needed and so there is no delay wrapper around the check
+ self._keymap_check = InputCheckHandler.add_check(self, None, self._checkKeymap)
+
+ # Run the keymap check on keymap changes
+ self._xkl_instance = XklWrapper.get_instance()
+ self._xkl_instance.engine.connect("X-state-changed", self.on_keymap_change)
+ self._xkl_instance.engine.connect("X-config-changed", self.on_keymap_change)
+
# the passphrase confirmation needs to be checked whenever either of the password
# fields change. attach to the confirm field and check changes to the
# password field in on_passphrase_changed
@@ -80,6 +95,9 @@ def __init__(self, data):
self._strength_check = self.add_check(self._passphrase_entry, self._checkStrength)
self._ascii_check = self.add_check(self._passphrase_entry, self._checkASCII)
+ # Initialize the keymap state
+ self._keymap_check.update_check_status()
+
def refresh(self):
super(PassphraseDialog, self).refresh()
@@ -163,6 +181,14 @@ def set_status(self, inputcheck):
# Set the warning message with the result from the first failed check
failed_check = next(self.failed_checks_with_message, None)
+ # If the keymap check failed, shutdown the input
+ if failed_check == self._keymap_check:
+ self._passphrase_entry.set_sensitive(False)
+ self._confirm_entry.set_sensitive(False)
+ else:
+ self._passphrase_entry.set_sensitive(True)
+ self._confirm_entry.set_sensitive(True)
+
if failed_check:
result_icon, result_message = failed_check.check_status
self._passphrase_warning_image.set_from_icon_name(result_icon, Gtk.IconSize.BUTTON)
@@ -180,6 +206,18 @@ def set_status(self, inputcheck):
else:
self._save_button.set_sensitive(False)
+ def _checkKeymap(self, inputcheck):
+ # Check whether the current keymap is ASCII-compatible. If not, it will
+ # not match the boot keymap, and it is not suitable for typing in a
+ # passphrase
+ keymap = self._xkl_instance.get_current_layout()
+ if not langtable.supports_ascii(keymap):
+ return ("dialog-error", _("The current keyboard layout does not match the keyboard layout "
+ "that will be used to unlock the encrypted partition. Using this keyboard layout to "
+ "input a passphrase could result in an unbootable system."))
+ else:
+ return InputCheck.CHECK_OK
+
def _checkASCII(self, inputcheck):
passphrase = self.get_input(inputcheck.input_obj)
@@ -222,3 +260,7 @@ def on_entry_activated(self, entry):
if self._save_button.get_sensitive() and \
entry.get_text() == self._passphrase_entry.get_text():
self._save_button.emit("clicked")
+
+ def on_keymap_change(self, *args):
+ # Update the keymap check
+ self._keymap_check.update_check_status()
diff --git a/pyanaconda/ui/gui/xkl_wrapper.py b/pyanaconda/ui/gui/xkl_wrapper.py
index b559eae..78d7de9 100644
--- a/pyanaconda/ui/gui/xkl_wrapper.py
+++ b/pyanaconda/ui/gui/xkl_wrapper.py
@@ -393,3 +393,7 @@ def set_switching_options(self, options):
msg = "Failed to set switching options to: %s" % ",".join(options)
raise XklWrapperError(msg)
+ @property
+ def engine(self):
+ """The underlying XklEngine object"""
+ return self._engine
--
To view this commit on github, visit https://github.com/rhinstaller/anaconda/commit/2942db81de78a0e98acf228822529861cd0d95e9
More information about the anaconda-patches
mailing list