diff --git a/qubes/ext/gui.py b/qubes/ext/gui.py index e542a360..feacb221 100644 --- a/qubes/ext/gui.py +++ b/qubes/ext/gui.py @@ -21,8 +21,11 @@ # License along with this library; if not, see . # +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,21 @@ 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 not len(untrusted_xkb_layout) == 3: + raise qubes.exc.QubesValueError + + untrusted_layout = untrusted_xkb_layout[0] + untrusted_variant = untrusted_xkb_layout[1] + untrusted_options = untrusted_xkb_layout[2] + + re_variant = '^[a-zA-Z0-9-_]+$' + re_options = '^[a-zA-Z0-9-_:,]+$' + + if not untrusted_layout.isalpha() or \ + not bool(re.match(re_variant, untrusted_variant)) or \ + not bool(re.match(re_options, untrusted_options)): + raise qubes.exc.QubesValueError