Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/pr/330'

* origin/pr/330:
  gui: fixes from Marek's comments
  gui: improvements of feature keyboard layout checks
  tests: adapt tests for keyboard-layout
  gui: drop legacy qubes-keyboard support
Marek Marczykowski-Górecki 4 gadi atpakaļ
vecāks
revīzija
8f0ec59f95
2 mainītis faili ar 41 papildinājumiem un 20 dzēšanām
  1. 23 10
      qubes/ext/gui.py
  2. 18 10
      qubes/tests/vm/qubesvm.py

+ 23 - 10
qubes/ext/gui.py

@@ -21,8 +21,11 @@
 # License along with this library; if not, see <https://www.gnu.org/licenses/>.
 #
 
+import re
+
 import qubes.config
 import qubes.ext
+import qubes.exc
 
 
 class GUI(qubes.ext.Extension):
@@ -96,16 +99,6 @@ class GUI(qubes.ext.Extension):
             if kbd_layout:
                 vm.untrusted_qdb.write('/keyboard-layout', kbd_layout)
 
-                # Legacy value for setting keyboard layout
-                xkb_keymap = \
-                    'xkb_keymap {\x0a\x09xkb_keycodes  { include ' \
-                    '"evdev"\x09};\x0a\x09xkb_types     { include ' \
-                    '"complete"\x09};\x0a\x09xkb_compat    { include ' \
-                    '"complete"\x09};\x0a\x09xkb_symbols   { include ' \
-                    '"pc+%s+inet(evdev)"\x09};\x0a\x09xkb_geometry  ' \
-                    '{ include "pc(pc105)"\x09};\x0a};' % kbd_layout
-                vm.untrusted_qdb.write('/qubes-keyboard', xkb_keymap)
-
         # Set GuiVM prefix
         guivm_windows_prefix = vm.features.get('guivm-windows-prefix', 'GuiVM')
         if vm.features.get('service.guivm-gui-agent', None):
@@ -128,3 +121,23 @@ class GUI(qubes.ext.Extension):
         for attached_vm in attached_vms:
             attached_vm.untrusted_qdb.write('/qubes-gui-domain-xid',
                                             str(vm.xid))
+
+    @qubes.ext.handler('domain-feature-pre-set:keyboard-layout')
+    def on_feature_pre_set(self, subject, event, feature, value, oldvalue=None):
+        untrusted_xkb_layout = value.split('+')
+        if len(untrusted_xkb_layout) != 3:
+            raise qubes.exc.QubesValueError("Invalid number of parameters")
+
+        untrusted_layout = untrusted_xkb_layout[0]
+        untrusted_variant = untrusted_xkb_layout[1]
+        untrusted_options = untrusted_xkb_layout[2]
+
+        re_variant = r'^[a-zA-Z0-9-_]*$'
+        re_options = r'^[a-zA-Z0-9-_:,]*$'
+
+        if not untrusted_layout.isalpha():
+            raise qubes.exc.QubesValueError("Invalid layout provided")
+        if not re.match(re_variant, untrusted_variant):
+            raise qubes.exc.QubesValueError("Invalid variant provided")
+        if not re.match(re_options, untrusted_options):
+            raise qubes.exc.QubesValueError("Invalid options provided")

+ 18 - 10
qubes/tests/vm/qubesvm.py

@@ -1832,14 +1832,7 @@ class TC_90_QubesVM(QubesVMTestsMixin, qubes.tests.QubesTestCase):
             name='appvm', qid=3)
         vm.netvm = None
         vm.guivm = guivm
-        guivm.features['keyboard-layout'] = 'fr'
-        xkb_keymap = \
-            'xkb_keymap {\x0a\x09xkb_keycodes  { include ' \
-            '"evdev"\x09};\x0a\x09xkb_types     { include ' \
-            '"complete"\x09};\x0a\x09xkb_compat    { include ' \
-            '"complete"\x09};\x0a\x09xkb_symbols   { include ' \
-            '"pc+fr+inet(evdev)"\x09};\x0a\x09xkb_geometry  ' \
-            '{ include "pc(pc105)"\x09};\x0a};'
+        guivm.features['keyboard-layout'] = 'fr++'
         guivm.is_running = lambda: True
         vm.events_enabled = True
         test_qubesdb = TestQubesDB()
@@ -1851,8 +1844,7 @@ class TC_90_QubesVM(QubesVMTestsMixin, qubes.tests.QubesTestCase):
             '/name': 'test-inst-appvm',
             '/type': 'AppVM',
             '/default-user': 'user',
-            '/qubes-keyboard': xkb_keymap,
-            '/keyboard-layout': 'fr',
+            '/keyboard-layout': 'fr++',
             '/qubes-vm-type': 'AppVM',
             '/qubes-gui-domain-xid': '{}'.format(guivm.xid),
             '/qubes-debug-mode': '0',
@@ -1918,6 +1910,22 @@ class TC_90_QubesVM(QubesVMTestsMixin, qubes.tests.QubesTestCase):
             '/connected-ips6': '',
         })
 
+    @unittest.mock.patch('qubes.utils.get_timezone')
+    @unittest.mock.patch('qubes.utils.urandom')
+    @unittest.mock.patch('qubes.vm.qubesvm.QubesVM.untrusted_qdb')
+    def test_624_qdb_guivm_invalid_keyboard_layout(self, mock_qubesdb,
+                                                   mock_urandom, mock_timezone):
+        mock_urandom.return_value = b'A' * 64
+        mock_timezone.return_value = 'UTC'
+        template = self.get_vm(
+            cls=qubes.vm.templatevm.TemplateVM, name='template')
+        guivm = self.get_vm(cls=qubes.vm.appvm.AppVM, template=template,
+            name='sys-gui', qid=2, provides_network=False)
+        guivm.is_running = lambda: True
+        guivm.events_enabled = True
+        with self.assertRaises(qubes.exc.QubesValueError):
+            guivm.features['keyboard-layout'] = 'fr123++'
+
     @asyncio.coroutine
     def coroutine_mock(self, mock, *args, **kwargs):
         return mock(*args, **kwargs)