summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am7
-rw-r--r--NEWS7
-rw-r--r--configure.ac13
-rw-r--r--src/locale/localed.c54
4 files changed, 80 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 3f9f3fab37..1674f6195a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4626,7 +4626,12 @@ systemd_localed_SOURCES = \
systemd_localed_LDADD = \
libsystemd-label.la \
libsystemd-internal.la \
- libsystemd-shared.la
+ libsystemd-shared.la \
+ $(XKBCOMMON_LIBS)
+
+systemd_localed_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(XKBCOMMON_CFLAGS)
nodist_systemunit_DATA += \
units/systemd-localed.service
diff --git a/NEWS b/NEWS
index f621752d64..0d3ab2b48b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
systemd System and Service Manager
+CHANGES WITH 218:
+
+ * If compiled with --enable-xkbcommon, systemd-localed will
+ verify x11 keymap settings by compiling the given keymap. It
+ will spew out warnings if the compilation fails. This
+ requires libxkbcommon to be installed.
+
CHANGES WITH 217:
* journalctl gained the new options -t/--identifier= to match
diff --git a/configure.ac b/configure.ac
index 2c8be53dd3..bd3cc0ea61 100644
--- a/configure.ac
+++ b/configure.ac
@@ -415,6 +415,18 @@ fi
AM_CONDITIONAL(HAVE_KMOD, [test "$have_kmod" = "yes"])
# ------------------------------------------------------------------------------
+have_xkbcommon=no
+AC_ARG_ENABLE(xkbcommon, AS_HELP_STRING([--disable-xkbcommon], [disable xkbcommon keymap support]))
+if test "x$enable_xkbcommon" != "xno"; then
+ PKG_CHECK_MODULES(XKBCOMMON, [ xkbcommon >= 0.3.0 ],
+ [AC_DEFINE(HAVE_XKBCOMMON, 1, [Define if libxkbcommon is available]) have_xkbcommon=yes], have_xkbcommon=no)
+ if test "x$have_xkbcommon" = xno -a "x$enable_xkbcommon" = xyes; then
+ AC_MSG_ERROR([*** xkbcommon support requested but libraries not found])
+ fi
+fi
+AM_CONDITIONAL(HAVE_XKBCOMMON, [test "$have_xkbcommon" = "yes"])
+
+# ------------------------------------------------------------------------------
have_blkid=no
AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid], [disable blkid support]))
if test "x$enable_blkid" != "xno"; then
@@ -1374,6 +1386,7 @@ AC_MSG_RESULT([
polkit: ${have_polkit}
efi: ${have_efi}
kmod: ${have_kmod}
+ xkbcommon: ${have_xkbcommon}
blkid: ${have_blkid}
dbus: ${have_dbus}
nss-myhostname: ${have_myhostname}
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 9377ce5015..4e56382f4f 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -41,6 +41,10 @@
#include "event-util.h"
#include "locale-util.h"
+#ifdef HAVE_XKBCOMMON
+#include <xkbcommon/xkbcommon.h>
+#endif
+
enum {
/* We don't list LC_ALL here on purpose. People should be
* using LANG instead. */
@@ -1005,6 +1009,51 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata
return sd_bus_reply_method_return(m, NULL);
}
+#ifdef HAVE_XKBCOMMON
+static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char *format, va_list args) {
+ /* suppress xkb messages for now */
+}
+
+static int verify_xkb_rmlvo(const char *model, const char *layout, const char *variant, const char *options) {
+ const struct xkb_rule_names rmlvo = {
+ .model = model,
+ .layout = layout,
+ .variant = variant,
+ .options = options,
+ };
+ struct xkb_context *ctx = NULL;
+ struct xkb_keymap *km = NULL;
+ int r;
+
+ /* compile keymap from RMLVO information to check out its validity */
+
+ ctx = xkb_context_new(XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
+ if (!ctx) {
+ r = -ENOMEM;
+ goto exit;
+ }
+
+ xkb_context_set_log_fn(ctx, log_xkb);
+
+ km = xkb_keymap_new_from_names(ctx, &rmlvo, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!km) {
+ r = -EINVAL;
+ goto exit;
+ }
+
+ r = 0;
+
+exit:
+ xkb_keymap_unref(km);
+ xkb_context_unref(ctx);
+ return r;
+}
+#else
+static int verify_xkb_rmlvo(const char *model, const char *layout, const char *variant, const char *options) {
+ return 0;
+}
+#endif
+
static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
const char *layout, *model, *variant, *options;
@@ -1038,6 +1087,11 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat
(options && !string_is_safe(options)))
return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data");
+ r = verify_xkb_rmlvo(model, layout, variant, options);
+ if (r < 0)
+ log_warning("Cannot compile XKB keymap for new x11 keyboard layout ('%s' / '%s' / '%s' / '%s'): %s",
+ strempty(model), strempty(layout), strempty(variant), strempty(options), strerror(-r));
+
r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
if (r < 0)
return r;